From patchwork Fri Dec 7 09:26:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009291 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="PNxF+toQ"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6tC3Gqjz9s55 for ; Fri, 7 Dec 2018 20:41:23 +1100 (AEDT) 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=3QBoJn5yva4KyNJXSgu75EBvSMQusYasVdKjmB2WfY4=; b=PNxF+toQUmSjAerOLM7BBLKCL6 CulNRtnQwsUGJVsZ2ad3uiXDUACqmqnufgcLX0gQUkxdmhf73uno0wZPFWQ3evSV7MUUD9wtpwf1s fxxtUOX8fTydy5mkmHT+9EchRzRsGD9/ZdYuQ+AaonRiCzHI3BNCQEd6IRMGgHAMHTgjSOHYbpHiL hBaUd+H9jEfRMwobBEEgd9dzbLiQmyb8kKNAfwSVja3o6GT99g4eSvatN5h32cE5nyeoeUy7dtGlA YejutCksRioBI8hOw1RmavZeRvAQz8l1ZmT2XVQAm8KdnNonEb31WhNuS2IqEbef7ncdS9CIoIJlo 4j8OsliQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCd3-0005V3-CM; Fri, 07 Dec 2018 09:41:01 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPT-0000wm-8k for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:02 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 2B67520E34; Fri, 7 Dec 2018 10:26:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id CEE6D20CC3; Fri, 7 Dec 2018 10:26:37 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 01/34] mtd: spi-nor: Add a new hook to let part specific code tweak the config Date: Fri, 7 Dec 2018 10:26:04 +0100 Message-Id: <20181207092637.18687-2-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012659_748970_E7390777 X-CRM114-Status: GOOD ( 16.07 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org SFDP tables are sometimes wrong and we need a way to override the config chosen by the SFDP parsing logic without discarding all of it. We also need a way to add chip specific tweaks when the SPI NOR does not support RDSFDP. Add a new hook called after the SFDP parsing has taken place to deal with such problems. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 298bc7a2f899..b2b36b2ea251 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -218,6 +218,11 @@ struct sfdp_bfpt { /** * struct spi_nor_fixups - SPI NOR fixup hooks * @post_bfpt: called after the BFPT table has been parsed + * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs + * that do not support RDSFDP). Typically used to tweak various + * parameters that could not be extracted by other means (i.e. + * when information provided by the SFDP/flash_info tables are + * incomplete or wrong). * * Those hooks can be used to tweak the SPI NOR configuration when the SFDP * table is broken or not available. @@ -227,6 +232,8 @@ struct spi_nor_fixups { const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt, struct spi_nor_flash_parameter *params); + int (*post_sfdp)(struct spi_nor *nor, + struct spi_nor_flash_parameter *params); }; struct flash_info { @@ -3658,6 +3665,15 @@ void spi_nor_restore(struct spi_nor *nor) } EXPORT_SYMBOL_GPL(spi_nor_restore); +static int spi_nor_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + if (nor->info->fixups && nor->info->fixups->post_sfdp) + return nor->info->fixups->post_sfdp(nor, params); + + return 0; +} + static const struct flash_info *spi_nor_match_id(const char *name) { const struct flash_info *id = spi_nor_ids; @@ -3805,6 +3821,18 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (info->flags & SPI_NOR_NO_FR) params.hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST; + /* + * Post SFDP fixups. Has to be called before spi_nor_setup() because + * some fixups might modify params that are then used by + * spi_nor_setup() to select the opcodes. + */ + ret = spi_nor_post_sfdp_fixups(nor, ¶ms); + if (ret) { + dev_err(dev, "failed in the post-SFDP fixups (err %d)\n", + ret); + return ret; + } + /* * Configure the SPI memory: * - select op codes for (Fast) Read, Page Program and Sector Erase. From patchwork Fri Dec 7 09:26:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009261 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="NXuUDLTz"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6Yx5Sctz9s3q for ; Fri, 7 Dec 2018 20:27:17 +1100 (AEDT) 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=UotayR2CuzqabyG0eTn7n0kwHCcrOCm6TNFGAd0sNh0=; b=NXuUDLTzhNV8J/V9HYjxe7Wzrl khxfjPQKXrRLs7tVFtc0UYXVPrGBZV0Yb5WVAJQ9nymIaUjwRvRaF8Q2Rf1o/OiLub4fY8GcZ+j3s z35gs46r9GAZSi11wFOttM/cJEMJPqIxA7vMATEVV3cSNC1KHH8LCJ5S/JwIJMwtP+2uIzJOqp3Vu T/ZvOQH2V/Pd7ODlbVeu1FBqNkoiFVGNI+XSGQPQwNfQs8hLM/sYEqRn+VeOerKzgp3Am+WNT3df5 djL4dl8ec7znSq3oVpQFI91Ygx5+rvTE6CeLB8k8OjjkORwZWvpuHJHI95ve14vF4cQufFffNf/Cg l5KGHXDQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPh-0001GU-Si; Fri, 07 Dec 2018 09:27:13 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPT-0000wq-8p for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:00 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 5A19320CC3; Fri, 7 Dec 2018 10:26:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 0F8F820CC5; Fri, 7 Dec 2018 10:26:38 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 02/34] mtd: spi-nor: Add a post SFDP fixup hook for gd25q256 Date: Fri, 7 Dec 2018 10:26:05 +0100 Message-Id: <20181207092637.18687-3-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012659_449739_CEB0BEE8 X-CRM114-Status: GOOD ( 14.76 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org gd25q256 needs to tweak the ->quad_enable() implementation and the ->post_sfdp() fixup hook is the perfect place to do that. This way, if we ever need to tweak more things for this flash, we won't have to add new fields in flash_info. We can get rid of the flash_info->quad_enable field as gd25q256 was the only user. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b2b36b2ea251..6b458ff4effa 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -287,8 +287,6 @@ struct flash_info { /* Part specific fixup hooks. */ const struct spi_nor_fixups *fixups; - - int (*quad_enable)(struct spi_nor *nor); }; #define JEDEC_MFR(info) ((info)->id[0]) @@ -1687,6 +1685,18 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) .addr_width = 3, \ .flags = SPI_NOR_NO_FR | SPI_S3AN, +static int gd25q256_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + params->quad_enable = macronix_quad_enable; + + return 0; +} + +static const struct spi_nor_fixups gd25q256_fixups = { + .post_sfdp = gd25q256_post_sfdp_fixups, +}; + static int mx25l25635_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, @@ -1800,7 +1810,7 @@ static const struct flash_info spi_nor_ids[] = { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - .quad_enable = macronix_quad_enable, + .fixups = &gd25q256_fixups, }, /* Intel/Numonyx -- xxxs33b */ @@ -3356,15 +3366,6 @@ static int spi_nor_init_params(struct spi_nor *nor, params->quad_enable = spansion_quad_enable; break; } - - /* - * Some manufacturer like GigaDevice may use different - * bit to set QE on different memories, so the MFR can't - * indicate the quad_enable method for this case, we need - * set it in flash info list. - */ - if (info->quad_enable) - params->quad_enable = info->quad_enable; } if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && From patchwork Fri Dec 7 09:26:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009289 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="khgiZdnT"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6t61yz9z9s3q for ; Fri, 7 Dec 2018 20:41:18 +1100 (AEDT) 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=dD8mUr+ol5VXl3z94u4BaaUGNFgNHgqaTcBU5boem/4=; b=khgiZdnTPCga9AJySbDjuqG/8m qrBVrVTK3MBnuK+qrK8g1Q8lODZIev+0mZ7CTEey6Ln1CWRkKncEiIjfwR5RJnmQZPTquchkrPNu6 N20QDLq5GCnFMsB1R5IkhlcQdnxkZXvOcGXju3eO0ONKYlfi1W0DEYNTNa2bVWHSm8v5fMgdW09n1 P6mwLhStpbVmiWP4TVsk8+8cPKv6jTnboo7m5VW/jfJD7C3iAB4clmc5dLDukOkTY/kuNqChk91t0 /YQyOkUGdvl4u4LGDXCAorT5rTZ5tQ6PTj5vKwlJNqV3EKkpEmRg4rYP2Oc8/JaHjotSC4CJHcsES ryORj++A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCdB-0005eJ-AT; Fri, 07 Dec 2018 09:41:09 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPT-0000wt-8o for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:02 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 93F6820CC5; Fri, 7 Dec 2018 10:26:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 4411920CDF; Fri, 7 Dec 2018 10:26:38 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 03/34] mtd: spi-nor: Create a ->set_4byte() method Date: Fri, 7 Dec 2018 10:26:06 +0100 Message-Id: <20181207092637.18687-4-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012659_742300_CD0226D5 X-CRM114-Status: GOOD ( 18.07 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The procedure used to enable 4 byte addressing mode depends on the NOR device, so let's provide a hook so that manufacturer specific handling can be implemented in a sane way. This is also an opportunity to create a per-manufacturer post SFDP fixups function where we'll put all the manufacturer specific tweaks. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 138 +++++++++++++++++++++++----------- include/linux/mtd/spi-nor.h | 3 + 2 files changed, 99 insertions(+), 42 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 6b458ff4effa..bea267c446b5 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -470,46 +470,15 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) /* Enable/disable 4-byte addressing mode. */ static int set_4byte(struct spi_nor *nor, bool enable) { - int status; - bool need_wren = false; - u8 cmd; + if (nor->set_4byte) + return nor->set_4byte(nor, enable); - switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_ST: - case SNOR_MFR_MICRON: - /* Some Micron need WREN command; all will accept it */ - need_wren = true; - /* fall through */ - case SNOR_MFR_MACRONIX: - case SNOR_MFR_WINBOND: - if (need_wren) - write_enable(nor); - - cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; - status = nor->write_reg(nor, cmd, NULL, 0); - if (need_wren) - write_disable(nor); - - if (!status && !enable && - JEDEC_MFR(nor->info) == SNOR_MFR_WINBOND) { - /* - * On Winbond W25Q256FV, leaving 4byte mode causes - * the Extended Address Register to be set to 1, so all - * 3-byte-address reads come from the second 16M. - * We must clear the register to enable normal behavior. - */ - write_enable(nor); - nor->cmd_buf[0] = 0; - nor->write_reg(nor, SPINOR_OP_WREAR, nor->cmd_buf, 1); - write_disable(nor); - } - - return status; - default: - /* Spansion style */ - nor->cmd_buf[0] = enable << 7; - return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1); - } + /* + * Spansion style. Should work for all NORs that do not have their own + * ->set_4byte() implementation. + */ + nor->cmd_buf[0] = enable << 7; + return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1); } static int s3an_sr_ready(struct spi_nor *nor) @@ -3666,13 +3635,98 @@ void spi_nor_restore(struct spi_nor *nor) } EXPORT_SYMBOL_GPL(spi_nor_restore); +static int macronix_set_4byte(struct spi_nor *nor, bool enable) +{ + return nor->write_reg(nor, enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B, + NULL, 0); +} + +static int st_micron_set_4byte(struct spi_nor *nor, bool enable) +{ + int ret; + + write_enable(nor); + ret = macronix_set_4byte(nor, enable); + write_disable(nor); + + return ret; +} + +static int winbond_set_4byte(struct spi_nor *nor, bool enable) +{ + int ret; + + ret = macronix_set_4byte(nor, enable); + if (ret || enable) + return ret; + + /* + * On Winbond W25Q256FV, leaving 4byte mode causes the Extended Address + * Register to be set to 1, so all 3-byte-address reads come from the + * second 16M. + * We must clear the register to enable normal behavior. + */ + write_enable(nor); + nor->cmd_buf[0] = 0; + nor->write_reg(nor, SPINOR_OP_WREAR, nor->cmd_buf, 1); + write_disable(nor); + + return ret; +} + +static void st_micron_post_sfdp_fixups(struct spi_nor *nor) +{ + nor->set_4byte = st_micron_set_4byte; +} + +static void macronix_post_sfdp_fixups(struct spi_nor *nor) +{ + nor->set_4byte = macronix_set_4byte; +} + +static void winbond_post_sfdp_fixups(struct spi_nor *nor) +{ + nor->set_4byte = winbond_set_4byte; +} + +static int +spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + switch (JEDEC_MFR(nor->info)) { + case SNOR_MFR_ST: + case SNOR_MFR_MICRON: + st_micron_post_sfdp_fixups(nor); + break; + + case SNOR_MFR_MACRONIX: + macronix_post_sfdp_fixups(nor); + break; + + case SNOR_MFR_WINBOND: + winbond_post_sfdp_fixups(nor); + break; + + default: + break; + } + + return 0; +} + static int spi_nor_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { - if (nor->info->fixups && nor->info->fixups->post_sfdp) - return nor->info->fixups->post_sfdp(nor, params); + int ret; - return 0; + ret = spi_nor_manufacturer_post_sfdp_fixups(nor, params); + if (ret) + return ret; + + if (nor->info->fixups && nor->info->fixups->post_sfdp) + ret = nor->info->fixups->post_sfdp(nor, params); + + return ret; } static const struct flash_info *spi_nor_match_id(const char *name) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 5f177aa39f68..d28a9913b165 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -365,6 +365,8 @@ struct flash_info; * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * completely locked + * @set_4byte: [FLASH-SPECIFIC] put the SPI NOR in 4 byte addressing + * mode * @priv: the private data */ struct spi_nor { @@ -401,6 +403,7 @@ struct spi_nor { int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*quad_enable)(struct spi_nor *nor); + int (*set_4byte)(struct spi_nor *nor, bool enable); void *priv; }; From patchwork Fri Dec 7 09:26:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009260 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="kgnubXh6"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6Ym0WXVz9s3q for ; Fri, 7 Dec 2018 20:27:08 +1100 (AEDT) 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=GCTTIGQeYgxYiHFuuj1pQXXUEOmQ04oSnh7psgdQMAs=; b=kgnubXh6UDHr4v1rbDzsQ0RpaT h0u6E0EzPlmJstrX5oG4kg6rT0Bnk+GfwRQplfFSonEyml8e1ZOI0xan851Gd1pg5rUxCU4RN4+FM s0nmWmXh/nZYa6J3ExwYHgcIFG5PtwqXJzOkSjPcp3CICjZxtkacv3c7cnPGMaiQ4A6sB5QUwbHag R1iDHtnYNI3u2eYiGkcYVxsl5x7x1xUoUK/UDrVHMlNFs2QFvQnAONdyjS5xKBv6X2jky4+i7CH3k sAbgBYmzn2HIpT5s9f2mg/z1VfTJ93+W8rW+PWByRWGNeN4k2BtGZixwr4p27buBkGZ5EF6xWW31Q Lmdyl8NQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPW-0000zu-S9; Fri, 07 Dec 2018 09:27:02 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPT-0000ww-8n for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:00 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id C28E120CDF; Fri, 7 Dec 2018 10:26:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 7AAF820CE3; Fri, 7 Dec 2018 10:26:38 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 04/34] mtd: spi-nor: Add spansion_fixups() Date: Fri, 7 Dec 2018 10:26:07 +0100 Message-Id: <20181207092637.18687-5-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012659_442847_50199EA3 X-CRM114-Status: GOOD ( 13.65 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add a spansion_post_sfdp_fixups() function to fix the erase opcode, erase sector size and set the SNOR_F_4B_OPCODES flag. This way, all spansion related quirks are placed in the spansion_post_sfdp_fixups() function. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index bea267c446b5..fd88b0a13115 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -438,18 +438,6 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode) static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) { - /* Do some manufacturer fixups first */ - switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_SPANSION: - /* No small sector erase for 4-byte command set */ - nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; - break; - - default: - break; - } - nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode); nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); @@ -3689,6 +3677,19 @@ static void winbond_post_sfdp_fixups(struct spi_nor *nor) nor->set_4byte = winbond_set_4byte; } +static void spansion_post_sfdp_fixups(struct spi_nor *nor) +{ + struct mtd_info *mtd = &nor->mtd; + + if (mtd->size > SZ_16M) { + nor->flags |= SNOR_F_4B_OPCODES; + + /* No small sector erase for 4-byte command set */ + nor->erase_opcode = SPINOR_OP_SE; + nor->mtd.erasesize = nor->info->sector_size; + } +} + static int spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) @@ -3703,6 +3704,10 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, macronix_post_sfdp_fixups(nor); break; + case SNOR_MFR_SPANSION: + spansion_post_sfdp_fixups(nor); + break; + case SNOR_MFR_WINBOND: winbond_post_sfdp_fixups(nor); break; @@ -3910,8 +3915,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->addr_width = 3; } - if (info->flags & SPI_NOR_4B_OPCODES || - (JEDEC_MFR(info) == SNOR_MFR_SPANSION && mtd->size > SZ_16M)) + if (info->flags & SPI_NOR_4B_OPCODES) nor->flags |= SNOR_F_4B_OPCODES; if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES) From patchwork Fri Dec 7 09:26:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009263 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="EcEFJ67b"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6Zv2xxbz9s3q for ; Fri, 7 Dec 2018 20:28:07 +1100 (AEDT) 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=V4byzMPEAnwl0C71Ewdm2OcGkZ5uKhrSyZFWugwppwU=; b=EcEFJ67bM/3dfvMFh5n/Ii3aKQ NUW4Q/8ORmLhhOzWwBrm2X1jqdRFccLTCRXZCkdnkaN8dPiO7/ZpBcPHYnOlvZr7VotKJOuSvbekv EsQFRQi42N1tIS6ZAgm4n+kYwgqt4UJp8aqcrEQPEKBvjx/TTM8lsDxrUXAmgcvS8e0pZzZgczWX7 szYZKxzhnW/LTTmLJgEr65PNbcx4KWLCED7QaJYwDWm0u8pSAxeMKZz5lQePIf7DgWdSZHvmGGpu1 7cbymR/8nLIz/XP4mlc3NFdrZlxN0r8x8BuE7jfR+qV8Z3z5A2rMxLr2WZlOThZi+VA9QRLf2ycQ1 JMNt7ppg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQU-00029R-33; Fri, 07 Dec 2018 09:28:02 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-0000zd-Bu for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:16 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 0457620CE3; Fri, 7 Dec 2018 10:26:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id AC96A20CE8; Fri, 7 Dec 2018 10:26:38 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 05/34] mtd: spi-nor: Rework the SPI NOR lock/unlock logic Date: Fri, 7 Dec 2018 10:26:08 +0100 Message-Id: <20181207092637.18687-6-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012711_938180_1305EB64 X-CRM114-Status: GOOD ( 18.61 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add the SNOR_F_HAS_LOCK flag and set it when SPI_NOR_HAS_LOCK is set in the flash_info entry or when it's a Micron or ST flash. We also move the locking hooks in a separate struct so that we just have one field to update when we change the locking implementation. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 45 +++++++++++++++++++++-------------- include/linux/mtd/spi-nor.h | 24 +++++++++++++------ 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index fd88b0a13115..1f15b93adc11 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1305,6 +1305,12 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) return stm_is_locked_sr(nor, ofs, len, status); } +static const struct spi_nor_locking_ops stm_locking_ops = { + .lock = stm_lock, + .unlock = stm_unlock, + .is_locked = stm_is_locked, +}; + static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct spi_nor *nor = mtd_to_spi_nor(mtd); @@ -1314,7 +1320,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_lock(nor, ofs, len); + ret = nor->locking_ops->lock(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); return ret; @@ -1329,7 +1335,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_unlock(nor, ofs, len); + ret = nor->locking_ops->unlock(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); return ret; @@ -1344,7 +1350,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_is_locked(nor, ofs, len); + ret = nor->locking_ops->is_locked(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); return ret; @@ -3664,6 +3670,8 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable) static void st_micron_post_sfdp_fixups(struct spi_nor *nor) { + /* All ST/Micron NORs support the unlock/lock operations. */ + nor->flags |= SNOR_F_HAS_LOCK; nor->set_4byte = st_micron_set_4byte; } @@ -3826,21 +3834,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, mtd->_read = spi_nor_read; mtd->_resume = spi_nor_resume; - /* NOR protection support for STmicro/Micron chips and similar */ - if (JEDEC_MFR(info) == SNOR_MFR_ST || - JEDEC_MFR(info) == SNOR_MFR_MICRON || - info->flags & SPI_NOR_HAS_LOCK) { - nor->flash_lock = stm_lock; - nor->flash_unlock = stm_unlock; - nor->flash_is_locked = stm_is_locked; - } - - if (nor->flash_lock && nor->flash_unlock && nor->flash_is_locked) { - mtd->_lock = spi_nor_lock; - mtd->_unlock = spi_nor_unlock; - mtd->_is_locked = spi_nor_is_locked; - } - /* sst nor chips use AAI word program */ if (info->flags & SST_WRITE) mtd->_write = sst_write; @@ -3881,6 +3874,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (info->flags & SPI_NOR_NO_FR) params.hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST; + if (info->flags & SPI_NOR_HAS_LOCK) + nor->flags |= SNOR_F_HAS_LOCK; + /* * Post SFDP fixups. Has to be called before spi_nor_setup() because * some fixups might modify params that are then used by @@ -3893,6 +3889,19 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, return ret; } + /* + * NOR protection support. When locking_ops are not provided, we + * pick the default ones. + */ + if (nor->flags & SNOR_F_HAS_LOCK && !nor->locking_ops) + nor->locking_ops = &stm_locking_ops; + + if (nor->locking_ops) { + mtd->_lock = spi_nor_lock; + mtd->_unlock = spi_nor_unlock; + mtd->_is_locked = spi_nor_is_locked; + } + /* * Configure the SPI memory: * - select op codes for (Fast) Read, Page Program and Sector Erase. diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index d28a9913b165..56e6bf4ee823 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -234,6 +234,7 @@ enum spi_nor_option_flags { SNOR_F_USE_CLSR = BIT(5), SNOR_F_BROKEN_RESET = BIT(6), SNOR_F_4B_OPCODES = BIT(7), + SNOR_F_HAS_LOCK = BIT(8), }; /** @@ -360,13 +361,10 @@ struct flash_info; * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR * at the offset @offs; if not provided by the driver, * spi-nor will send the erase opcode via write_reg() - * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR - * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR - * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode - * completely locked * @set_4byte: [FLASH-SPECIFIC] put the SPI NOR in 4 byte addressing * mode + * @locking_ops: [FLASH-SPECIFIC] SPI NOR locking methods * @priv: the private data */ struct spi_nor { @@ -399,15 +397,27 @@ struct spi_nor { size_t len, const u_char *write_buf); int (*erase)(struct spi_nor *nor, loff_t offs); - int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*quad_enable)(struct spi_nor *nor); int (*set_4byte)(struct spi_nor *nor, bool enable); + const struct spi_nor_locking_ops *locking_ops; + void *priv; }; +/** + * struct spi_nor_locking_ops - SPI NOR locking methods + * @lock: lock a region of the SPI NOR + * @unlock: unlock a region of the SPI NOR + * @is_locked: check if a region of the SPI NOR is completely locked + */ +struct spi_nor_locking_ops { + int (*lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); + int (*unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); + int (*is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); +}; + + static u64 __maybe_unused spi_nor_region_is_last(const struct spi_nor_erase_region *region) { From patchwork Fri Dec 7 09:26:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009272 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="puGcfwbM"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6dS19HBz9s3q for ; Fri, 7 Dec 2018 20:30:20 +1100 (AEDT) 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=ebhWIgW+PqwOgb2tWMPO5c97shSOspKizKT4turGSR4=; b=puGcfwbMac3RFxrInIJuZ07eIV emjjNKUuu3Dc7zFyJLRzKJC9SFNdG2YkH9l/bPX54J3j1Ln6QgtOO16744G9NTq3b0wTyQ/r9oDhb xXvmFXeI1vuLSOoRk4chG35LhidGFjUIGvMYbkdJWPcCvRWdYpKixgzWNFlLovBzPMStq2R0d2nqv HMb6r1AgtgKeR8x91TTrui5K5qHL3hM8AO9Us3gPMiZq9J1fZVBF3VbUj3yaI7jEKxXLfkr5d2LmM HYvZJk5fN2DzzLxFKwsjTquhsZh3ZYH08SXgiIdjRggTVwuMdELPrOzKCvFSgfLFNu7IVFxuVcMje roaXMzIw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCSd-0004mV-2D; Fri, 07 Dec 2018 09:30:15 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-0000zc-Bp for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:31 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 44C8A20CE8; Fri, 7 Dec 2018 10:26:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id DED3A20CEB; Fri, 7 Dec 2018 10:26:38 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 06/34] mtd: spi-nor: Rework the ->quad_enable() selection logic Date: Fri, 7 Dec 2018 10:26:09 +0100 Message-Id: <20181207092637.18687-7-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_478007_63F083E1 X-CRM114-Status: GOOD ( 17.05 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The goal is to move the quad_enable manufacturer specific init in the _post_sfdp_fixups() hooks. First thing we do is add a spi_nor_quad_enable() wrapper that only calls nor->quad_enable() when needed (when Quad opcodes are selected). This way we can populate nor->quad_enable() without risking a switch to Quad mode when we don't expect it. Second thing we do is add an explicit no_quad_enable() implementation so that params->quad_enable() is no longer NULL when BFPT_DWORD15_QER_NONE is detected, and we can easily override any manufacturer specific function when SFDP parsing succeeds. And the last thing we do is move the default nor->quad_enable init in spi_nor_scan() and the manufacturer specific init in _post_sfdp_fixups(). Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 60 ++++++++++++++++------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 1f15b93adc11..049b67b8f986 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1385,6 +1385,11 @@ static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr) return 0; } +static int no_quad_enable(struct spi_nor *nor) +{ + return 0; +} + /** * macronix_quad_enable() - set QE bit in Status Register. * @nor: pointer to a 'struct spi_nor' @@ -2836,7 +2841,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, /* Quad Enable Requirements. */ switch (bfpt.dwords[BFPT_DWORD(15)] & BFPT_DWORD15_QER_MASK) { case BFPT_DWORD15_QER_NONE: - params->quad_enable = NULL; + params->quad_enable = no_quad_enable; break; case BFPT_DWORD15_QER_SR2_BIT1_BUGGY: @@ -3312,25 +3317,6 @@ static int spi_nor_init_params(struct spi_nor *nor, SPINOR_OP_SE); spi_nor_init_uniform_erase_map(map, erase_mask, params->size); - /* Select the procedure to set the Quad Enable bit. */ - if (params->hwcaps.mask & (SNOR_HWCAPS_READ_QUAD | - SNOR_HWCAPS_PP_QUAD)) { - switch (JEDEC_MFR(info)) { - case SNOR_MFR_MACRONIX: - params->quad_enable = macronix_quad_enable; - break; - - case SNOR_MFR_ST: - case SNOR_MFR_MICRON: - break; - - default: - /* Kept only for backward compatibility purpose. */ - params->quad_enable = spansion_quad_enable; - break; - } - } - if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && !(info->flags & SPI_NOR_SKIP_SFDP)) { struct spi_nor_flash_parameter sfdp_params; @@ -3510,7 +3496,6 @@ static int spi_nor_setup(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps) { u32 ignored_mask, shared_mask; - bool enable_quad_io; int err; /* @@ -3556,16 +3541,24 @@ static int spi_nor_setup(struct spi_nor *nor, } /* Enable Quad I/O if needed. */ - enable_quad_io = (spi_nor_get_protocol_width(nor->read_proto) == 4 || - spi_nor_get_protocol_width(nor->write_proto) == 4); - if (enable_quad_io && params->quad_enable) + if (params->quad_enable) nor->quad_enable = params->quad_enable; - else - nor->quad_enable = NULL; return 0; } +static int spi_nor_quad_enable(struct spi_nor *nor) +{ + if (spi_nor_get_protocol_width(nor->read_proto) != 4 && + spi_nor_get_protocol_width(nor->write_proto) != 4) + return 0; + + if (!nor->quad_enable) + return 0; + + return nor->quad_enable(nor); +} + static int spi_nor_init(struct spi_nor *nor) { int err; @@ -3583,12 +3576,10 @@ static int spi_nor_init(struct spi_nor *nor) spi_nor_wait_till_ready(nor); } - if (nor->quad_enable) { - err = nor->quad_enable(nor); - if (err) { - dev_err(nor->dev, "quad mode not supported\n"); - return err; - } + err = spi_nor_quad_enable(nor); + if (err) { + dev_err(nor->dev, "quad mode not supported\n"); + return err; } if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) { @@ -3673,11 +3664,13 @@ static void st_micron_post_sfdp_fixups(struct spi_nor *nor) /* All ST/Micron NORs support the unlock/lock operations. */ nor->flags |= SNOR_F_HAS_LOCK; nor->set_4byte = st_micron_set_4byte; + nor->quad_enable = no_quad_enable; } static void macronix_post_sfdp_fixups(struct spi_nor *nor) { nor->set_4byte = macronix_set_4byte; + nor->quad_enable = macronix_quad_enable; } static void winbond_post_sfdp_fixups(struct spi_nor *nor) @@ -3877,6 +3870,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (info->flags & SPI_NOR_HAS_LOCK) nor->flags |= SNOR_F_HAS_LOCK; + /* Kept only for backward compatibility purpose. */ + nor->quad_enable = spansion_quad_enable; + /* * Post SFDP fixups. Has to be called before spi_nor_setup() because * some fixups might modify params that are then used by From patchwork Fri Dec 7 09:26:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009268 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="UG6rnj8G"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6cf4chXz9s3q for ; Fri, 7 Dec 2018 20:29:38 +1100 (AEDT) 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=bUi9Qa1vWS/HUnarHruUMxNWoQOJT4jq7hSWrERT+Pc=; b=UG6rnj8GYUSVCj0mlnbX56gB1V 3NLm8lFAVywwz2YuXBEPLr0sl2jcpeUUQSt55sWJvrT7BTz31bDKO8ml8nbzggNL1sHD7Q9xEpVFf KtR5f4CvsnYerrFxlrX19Pre8eUcUxV5f/4mb71XVdluxJfVCRxxhj+1gXZF2pt3i2KYFlLh4Ww0Z +V5jnLjtxbh5aT7K7pvGQ15kB55W7J6YoJSe8WxCfvtnvYGuHkrh9tCKeiPMTCMHEJ7ND2YxBNv8C P9/tk/3UznH6H1f/i8Oq6vefTUvOkbB4WY4/AgDdOZKD4ffZ+bxUW9nL+pimO3LDe7wiuEMxFri3E 5gXXzfow==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCRv-0003SH-Lw; Fri, 07 Dec 2018 09:29:31 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-0000zg-Bt for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:30 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id CEFAC20CEB; Fri, 7 Dec 2018 10:26:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 2413F20CEC; Fri, 7 Dec 2018 10:26:39 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 07/34] mtd: spi-nor: Add a new flag to clear SW protection bits during init Date: Fri, 7 Dec 2018 10:26:10 +0100 Message-Id: <20181207092637.18687-8-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_519588_3B7B9547 X-CRM114-Status: GOOD ( 14.48 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Get rid of the last piece of code doing checks on SNOR_MFR to decide what to do. We add a new SNOR_F flag to explicitly ask for a SR clear at init time and this flag is set in spi_nor_scan() when the NOR supports the locking feature or directly from the SST, Intel and Atmel post-SFDP fixups hooks since NORs from those manufacturers always require clearing the protection bits. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 33 +++++++++++++++++++++++++++++---- include/linux/mtd/spi-nor.h | 1 + 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 049b67b8f986..ffea0085b4fe 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -3567,10 +3567,7 @@ static int spi_nor_init(struct spi_nor *nor) * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up * with the software protection bits set */ - if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL || - JEDEC_MFR(nor->info) == SNOR_MFR_INTEL || - JEDEC_MFR(nor->info) == SNOR_MFR_SST || - nor->info->flags & SPI_NOR_HAS_LOCK) { + if (nor->flags & SNOR_F_CLR_SW_PROT_BITS) { write_enable(nor); write_sr(nor, 0); spi_nor_wait_till_ready(nor); @@ -3691,11 +3688,34 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor) } } +static void intel_post_sfdp_fixups(struct spi_nor *nor) +{ + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; +} + +static void atmel_post_sfdp_fixups(struct spi_nor *nor) +{ + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; +} + +static void sst_post_sfdp_fixups(struct spi_nor *nor) +{ + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; +} + static int spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { switch (JEDEC_MFR(nor->info)) { + case SNOR_MFR_ATMEL: + atmel_post_sfdp_fixups(nor); + break; + + case SNOR_MFR_INTEL: + intel_post_sfdp_fixups(nor); + break; + case SNOR_MFR_ST: case SNOR_MFR_MICRON: st_micron_post_sfdp_fixups(nor); @@ -3709,6 +3729,10 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, spansion_post_sfdp_fixups(nor); break; + case SNOR_MFR_SST: + sst_post_sfdp_fixups(nor); + break; + case SNOR_MFR_WINBOND: winbond_post_sfdp_fixups(nor); break; @@ -3896,6 +3920,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, mtd->_lock = spi_nor_lock; mtd->_unlock = spi_nor_unlock; mtd->_is_locked = spi_nor_is_locked; + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; } /* diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 56e6bf4ee823..73dad2a77455 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -235,6 +235,7 @@ enum spi_nor_option_flags { SNOR_F_BROKEN_RESET = BIT(6), SNOR_F_4B_OPCODES = BIT(7), SNOR_F_HAS_LOCK = BIT(8), + SNOR_F_CLR_SW_PROT_BITS = BIT(9), }; /** From patchwork Fri Dec 7 09:26:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009294 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Mp1GQrCj"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6tb1lvRz9s55 for ; Fri, 7 Dec 2018 20:41:43 +1100 (AEDT) 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=ugZacPigTAs/JJOmDCmrWyyEWIwfj89GcVIZWm4J7j8=; b=Mp1GQrCjAh3eEDlz8aeCwTBZh3 j7KhQBTaWeMMCHHPi0LO28jA4qPByx8CHY9UJHqf/iB4iZ9xKBOBJ4ZIUaZoCsApqnWURnYd50Fr7 4/hj7AXNmimCruxrXbgeUBqP8mjTp/E1P42SJ7KLCQwssnZ9NE5BtMAiE3iN4Z+BLqHlg9hv+zGHG dQ2grBwzKw5bI4MjRtErUQM4lVXPHWXEJcxG4+jwCe6F9CNhxjsvL0r5CRRNLxQv3CmXWbLbdFz/W 5ASdhobt8+/tmSBlWlAdLU7zQ7GfV5VpWRoh60zBknTTD1/QNFPW3QYAjxNzXrqIG4kxSqshjr/WU dS8jv8wg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCdU-00061N-4b; Fri, 07 Dec 2018 09:41:28 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-000101-Bx for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:21 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id D98D320DC0; Fri, 7 Dec 2018 10:26:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 5B19920DBC; Fri, 7 Dec 2018 10:26:39 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 08/34] mtd: spi-nor: Add a ->convert_addr() method Date: Fri, 7 Dec 2018 10:26:11 +0100 Message-Id: <20181207092637.18687-9-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_424484_5CEAF10B X-CRM114-Status: GOOD ( 17.42 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org In order to separate manufacturer quirks from the core we need to get rid of all the manufacturer specific flags, like the SNOR_F_S3AN_ADDR_DEFAULT one. This can easily be replaced by a ->convert_addr() hook, which when implemented will provide the core with an easy way to convert an absolute address into something the flash understands. Right now the only user are the S3AN chips, but other manufacturers can implement it if needed. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 24 ++++++++++++++---------- include/linux/mtd/spi-nor.h | 17 ++++++++++------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index ffea0085b4fe..f6b1c9b8079a 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -622,10 +622,9 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) * Addr can safely be unsigned int, the biggest S3AN device is smaller than * 4 MiB. */ -static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) +static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) { - unsigned int offset; - unsigned int page; + u32 offset, page; offset = addr % nor->page_size; page = addr / nor->page_size; @@ -634,6 +633,14 @@ static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) return page | offset; } +static u32 spi_nor_convert_addr(struct spi_nor *nor, u32 addr) +{ + if (!nor->convert_addr) + return addr; + + return nor->convert_addr(nor, addr); +} + /* * Initiate the erasure of a single sector */ @@ -642,8 +649,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) u8 buf[SPI_NOR_MAX_ADDR_WIDTH]; int i; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); if (nor->erase) return nor->erase(nor, addr); @@ -2054,8 +2060,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, while (len) { loff_t addr = from; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); ret = nor->read(nor, addr, len, buf); if (ret == 0) { @@ -2199,8 +2204,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, page_remain = min_t(size_t, nor->page_size - page_offset, len - i); - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); write_enable(nor); ret = nor->write(nor, addr, page_remain, buf + i); @@ -2266,7 +2270,7 @@ static int s3an_nor_scan(struct spi_nor *nor) nor->mtd.erasesize = 8 * nor->page_size; } else { /* Flash in Default addressing mode */ - nor->flags |= SNOR_F_S3AN_ADDR_DEFAULT; + nor->convert_addr = s3an_convert_addr; } return 0; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 73dad2a77455..2c8fbd5d614d 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -229,13 +229,12 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB = BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), - SNOR_F_READY_XSR_RDY = BIT(4), - SNOR_F_USE_CLSR = BIT(5), - SNOR_F_BROKEN_RESET = BIT(6), - SNOR_F_4B_OPCODES = BIT(7), - SNOR_F_HAS_LOCK = BIT(8), - SNOR_F_CLR_SW_PROT_BITS = BIT(9), + SNOR_F_READY_XSR_RDY = BIT(3), + SNOR_F_USE_CLSR = BIT(4), + SNOR_F_BROKEN_RESET = BIT(5), + SNOR_F_4B_OPCODES = BIT(6), + SNOR_F_HAS_LOCK = BIT(7), + SNOR_F_CLR_SW_PROT_BITS = BIT(8), }; /** @@ -365,6 +364,9 @@ struct flash_info; * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @set_4byte: [FLASH-SPECIFIC] put the SPI NOR in 4 byte addressing * mode + * @convert_addr: [FLASH-SPECIFIC] convert an absolute address into + * something the flash will understand. Particularly + * useful when pagesize is not a power-of-2 * @locking_ops: [FLASH-SPECIFIC] SPI NOR locking methods * @priv: the private data */ @@ -400,6 +402,7 @@ struct spi_nor { int (*quad_enable)(struct spi_nor *nor); int (*set_4byte)(struct spi_nor *nor, bool enable); + u32 (*convert_addr)(struct spi_nor *nor, u32 addr); const struct spi_nor_locking_ops *locking_ops; From patchwork Fri Dec 7 09:26:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009292 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="VsVZWw/H"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6tS71plz9s3l for ; Fri, 7 Dec 2018 20:41:36 +1100 (AEDT) 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=eMsR58N/G3X/ruz7ZaEwzvjBKoGlk3eOdYYoQC3odcg=; b=VsVZWw/HWWPNU9xW5lUzDa4li6 bhY8eS6rkBF5d2mM9P3h91xLC4w8+RCRgGDpJB9eMAZfqzRz5WDR3lwXZVe409keTR9cDiZ8WBy1Z IHdyokEWQnPakrGDqEtv2taV5rpG3+FXuSVvnPKvHw17+r51LuI5Byq1tu8xvwDurKvdRSNJuxxFL TEFZBsKrtlfwjpssl0BGSvZCAlLLCeWtclhL/jfXxzJr+6yG0MvRZ+A+l8JA3gKS0IX4XbJkS/xFJ EOH6fzwy6y4wKo4na4EsAhWnEuFyOH/SZbEJc8+S9mO2luz/b7kEsW7Cjrl5hnAKINnJ7CMzA26Up 0RPkioJA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCdP-0005vs-Oo; Fri, 07 Dec 2018 09:41:23 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-0000zf-Bn for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:21 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id D5CAF20CEC; Fri, 7 Dec 2018 10:26:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 8FB9F20DC0; Fri, 7 Dec 2018 10:26:39 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 09/34] mtd: spi-nor: Add a flag to skip spi_nor_setup() Date: Fri, 7 Dec 2018 10:26:12 +0100 Message-Id: <20181207092637.18687-10-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_604314_C7291428 X-CRM114-Status: GOOD ( 12.53 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Some manufacturers select the opcode to use in their fixups() method, and they don't want the generic selection logic to override their values. Add a flag to allow that. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 7 +++++++ include/linux/mtd/spi-nor.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index f6b1c9b8079a..30dbddabec74 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -3502,6 +3502,13 @@ static int spi_nor_setup(struct spi_nor *nor, u32 ignored_mask, shared_mask; int err; + /* + * Some manufacturers select the opcode to use in their fixups() + * method, and explicitly ask to skip the generic selection logic. + */ + if (nor->flags & SNOR_F_SKIP_SETUP) + return 0; + /* * Keep only the hardware capabilities supported by both the SPI * controller and the SPI flash memory. diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 2c8fbd5d614d..8c64f1dcd35e 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -235,6 +235,7 @@ enum spi_nor_option_flags { SNOR_F_4B_OPCODES = BIT(6), SNOR_F_HAS_LOCK = BIT(7), SNOR_F_CLR_SW_PROT_BITS = BIT(8), + SNOR_F_SKIP_SETUP = BIT(9), }; /** From patchwork Fri Dec 7 09:26:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009262 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="aj+x9vdu"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6Zh0Jwsz9s55 for ; Fri, 7 Dec 2018 20:27:56 +1100 (AEDT) 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=gU6faJFB959+kHvIbmi239mzw+ry/RBqnB8v2ObFBTA=; b=aj+x9vdulsFvTPOeBPGOJ2wWPI uU3hRv4kXF4ZZPZb26WOuRMgLKee+e2xfilbxLVzCJuxIxSRp//uZaig+pI0l6LtAc/fpJWaTfGY1 S4Mb2QaptBY1aUQ3nW83ob+FlFL8Mxf6ri7uQwEprOgbKLBeHGVgBvjsJTLIdQKP1b2/eHeH8+MFb A/6Mq8bcxTvfujRRYi278lx30EP8++R8av/mYGEkahtUumdgDhi8Sajf90yqakiWsr6btJ7cXXPeZ 3NK64FR3heUoOEzsH4S0/QAKM5nWlfTH3o+ueSgI6e2awcKYxtjNCTeo7NdSAlpTLFQaYQMKfJlAA QcLZmv4g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQF-0001um-8G; Fri, 07 Dec 2018 09:27:47 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-000102-Bm for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:16 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id E071E20DBC; Fri, 7 Dec 2018 10:26:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id C5C5B20DC9; Fri, 7 Dec 2018 10:26:39 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 10/34] mtd: spi-nor: Add the SPI_NOR_XSR_RDY flag Date: Fri, 7 Dec 2018 10:26:13 +0100 Message-Id: <20181207092637.18687-11-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_414258_6CCA33E5 X-CRM114-Status: GOOD ( 13.13 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org S3AN flashes use a specific opcode to read the status register. We currently use the SPI_S3AN flag to decide whether this specific SR read opcode should be used, but SPI_S3AN is about to disappear, so let's add a new flag. Note that we use the same bit as SPI_S3AN implies SPI_NOR_XSR_RDY and vice versa. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 30dbddabec74..e805976ad784 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -271,6 +271,14 @@ struct flash_info { * bit. Must be used with * SPI_NOR_HAS_LOCK. */ +#define SPI_NOR_XSR_RDY BIT(10) /* + * S3AN flashes have specific opcode to + * read the status register. + * Flags SPI_NOR_XSR_RDY and SPI_S3AN + * use the same bit as one implies the + * other, but we will get rid of + * SPI_S3AN soon. + */ #define SPI_S3AN BIT(10) /* * Xilinx Spartan 3AN In-System Flash * (MFR cannot be used for probing @@ -3843,7 +3851,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, * spi_nor_wait_till_ready(). Xilinx S3AN share MFR * with Atmel spi-nor */ - if (info->flags & SPI_S3AN) + if (info->flags & SPI_NOR_XSR_RDY) nor->flags |= SNOR_F_READY_XSR_RDY; /* Parse the Serial Flash Discoverable Parameters table. */ From patchwork Fri Dec 7 09:26:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009267 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="EYFNJB1K"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6br5fJxz9s3q for ; Fri, 7 Dec 2018 20:28:56 +1100 (AEDT) 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=BVSAAvC+Ssv4VhghNzr/xbu7pHsUi+vkhXqvSdTvhmc=; b=EYFNJB1K2trBj8HxQJ25M3Vds2 51vqTCl5ZsS8ZNmEE+NdxS1qR5O/jBTqC4jI4a00ZM5Ac/HXr3DNhDpmEWKKx7AfzDGyaL+7AZrXI xPvjzn3B2nzXjrWov7i9OVMkxwWqFTwdm2YM7MAyBTYUbthALGz5Zrl0HSz5Q+oI0R3sF0JfXW0si PCBDNfG+cObM8EmpqtCz6WEnE/Vc22zAo1PEU1/MC+CKyjVkPVpB/bNTOQ2TFU/MBLLuSS/rhwC2r bYJIHcftjLzzDN/vCg4Qr0EEeGTqnZPrSX2rabRWuDLBR+rtRyQGjDsht9S4McGzqnmoY+ZSXzHlZ wX3UFJSQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCRG-0002qZ-3S; Fri, 07 Dec 2018 09:28:50 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-000109-Bo for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:21 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 3B76820DC9; Fri, 7 Dec 2018 10:26:51 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 05D9720DD3; Fri, 7 Dec 2018 10:26:40 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 11/34] mtd: spi-nor: Move S3AN fixups to the manufacturer fixups path Date: Fri, 7 Dec 2018 10:26:14 +0100 Message-Id: <20181207092637.18687-12-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_724771_50DB3C4F X-CRM114-Status: GOOD ( 18.84 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org All manufacturer fixups are grouped together with the method suffixed by _post_sfdp_fixups(). Let's do the same for the S3AN fixups. Note that s3an_nor_scan() was overriding the opcode selection done in spi_nor_setup(). Now that this function is called before spi_nor_setup(), we have to set SNOR_F_SKIP_SETUP. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 98 ++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index e805976ad784..34d3d632e53b 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -2243,47 +2243,6 @@ static int spi_nor_check(struct spi_nor *nor) return 0; } -static int s3an_nor_scan(struct spi_nor *nor) -{ - int ret; - u8 val; - - ret = nor->read_reg(nor, SPINOR_OP_XRDSR, &val, 1); - if (ret < 0) { - dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret); - return ret; - } - - nor->erase_opcode = SPINOR_OP_XSE; - nor->program_opcode = SPINOR_OP_XPP; - nor->read_opcode = SPINOR_OP_READ; - nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; - - /* - * This flashes have a page size of 264 or 528 bytes (known as - * Default addressing mode). It can be changed to a more standard - * Power of two mode where the page size is 256/512. This comes - * with a price: there is 3% less of space, the data is corrupted - * and the page size cannot be changed back to default addressing - * mode. - * - * The current addressing mode can be read from the XRDSR register - * and should not be changed, because is a destructive operation. - */ - if (val & XSR_PAGESIZE) { - /* Flash in Power of 2 mode */ - nor->page_size = (nor->page_size == 264) ? 256 : 512; - nor->mtd.writebufsize = nor->page_size; - nor->mtd.size = 8 * nor->page_size * nor->info->n_sectors; - nor->mtd.erasesize = 8 * nor->page_size; - } else { - /* Flash in Default addressing mode */ - nor->convert_addr = s3an_convert_addr; - } - - return 0; -} - static void spi_nor_set_read_settings(struct spi_nor_read_command *read, u8 num_mode_clocks, @@ -3722,6 +3681,54 @@ static void sst_post_sfdp_fixups(struct spi_nor *nor) nor->flags |= SNOR_F_CLR_SW_PROT_BITS; } +static int s3an_post_sfdp_fixups(struct spi_nor *nor) +{ + int ret; + u8 val; + + ret = nor->read_reg(nor, SPINOR_OP_XRDSR, &val, 1); + if (ret < 0) { + dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret); + return ret; + } + + /* + * We choose the opcodes we want to use, so let's add + * SNOR_F_SKIP_SETUP to prevent spi_nor_setup() from changing + * them behind our back. + */ + nor->flags |= SNOR_F_SKIP_SETUP; + nor->erase_opcode = SPINOR_OP_XSE; + nor->program_opcode = SPINOR_OP_XPP; + nor->read_opcode = SPINOR_OP_READ; + nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; + + /* + * This flashes have a page size of 264 or 528 bytes (known as + * Default addressing mode). It can be changed to a more standard + * Power of two mode where the page size is 256/512. This comes + * with a price: there is 3% less of space, the data is corrupted + * and the page size cannot be changed back to default addressing + * mode. + * + * The current addressing mode can be read from the XRDSR register + * and should not be changed, because is a destructive operation. + */ + if (val & XSR_PAGESIZE) { + /* Flash in Power of 2 mode */ + nor->page_size = (nor->page_size == 264) ? 256 : 512; + nor->mtd.writebufsize = nor->page_size; + nor->mtd.size = 8 * nor->page_size * nor->info->n_sectors; + nor->mtd.erasesize = 8 * nor->page_size; + } else { + /* Flash in Default addressing mode */ + nor->convert_addr = s3an_convert_addr; + } + + return 0; +} + + static int spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) @@ -3760,6 +3767,9 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, break; } + if (nor->info->flags & SPI_S3AN) + return s3an_post_sfdp_fixups(nor); + return 0; } @@ -3976,12 +3986,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, return -EINVAL; } - if (info->flags & SPI_S3AN) { - ret = s3an_nor_scan(nor); - if (ret) - return ret; - } - /* Send all the required SPI flash commands to initialize device */ ret = spi_nor_init(nor); if (ret) From patchwork Fri Dec 7 09:26:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009273 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="bwQGaey3"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6dk15gCz9s3q for ; Fri, 7 Dec 2018 20:30:34 +1100 (AEDT) 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=rrKBKR6Zpf7QEz4n42oQzVIXN4RfLThHN9zdsWpT/K4=; b=bwQGaey3o46cK7sSZg2S7qcIwB iOZQ+bOPeOmtzMLonzs0CF1AejEoRyPWAeDjpXV7UqMLqJGqraCLbjnJQLHlzOFmFuhLFrv7BpM5T RUgMkk6+qbo9vwLJoYX+2zSuCK3/kelNlcVzbQpZEXKK3L4przk68EatFO4jnPkpXoaplTX+9xqSN j+FAUH+MvRzmsgLKK/mmA48aLHQBIW6JMoM33EolTR8mCcPhacHYXDFq0JmErc4JQIrI6i+Cg9+0+ zn+HjHfufK0ulNxeboxy6N2J4ZQLbrNUNSR598QC+zeIPvmgfRq2eUauug50nNJZVxGnKlLS4DvTW b2Y464fw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCSs-0005gY-GM; Fri, 07 Dec 2018 09:30:30 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-00010B-Bs for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:33 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 4C01320E0C; Fri, 7 Dec 2018 10:26:51 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 3A4FD20DDA; Fri, 7 Dec 2018 10:26:40 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 12/34] mtd: spi-nor: Prepare things for core / manufacturer code split Date: Fri, 7 Dec 2018 10:26:15 +0100 Message-Id: <20181207092637.18687-13-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_069186_68807FF9 X-CRM114-Status: GOOD ( 21.92 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org First thing we do is move all SPI NOR controller drivers to a controllers/ sub-directory so that we only have SPI NOR related source files under drivers/mtd/spi-nor/. We then rename spi-nor.c into core.c since we are about to split this file in multiple source files (one per manufacturer, plus one for the SFDP parsing logic). Finally, we move some of the spi-nor.c internal definitions in internals.h so that they can be used by manufacturer drivers. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Kconfig | 108 +----- drivers/mtd/spi-nor/Makefile | 14 +- drivers/mtd/spi-nor/controllers/Kconfig | 107 ++++++ drivers/mtd/spi-nor/controllers/Makefile | 12 + .../spi-nor/{ => controllers}/aspeed-smc.c | 0 .../spi-nor/{ => controllers}/atmel-quadspi.c | 0 .../{ => controllers}/cadence-quadspi.c | 0 .../spi-nor/{ => controllers}/fsl-quadspi.c | 0 .../mtd/spi-nor/{ => controllers}/hisi-sfc.c | 0 .../spi-nor/{ => controllers}/intel-spi-pci.c | 0 .../{ => controllers}/intel-spi-platform.c | 0 .../mtd/spi-nor/{ => controllers}/intel-spi.c | 0 .../mtd/spi-nor/{ => controllers}/intel-spi.h | 0 .../spi-nor/{ => controllers}/mtk-quadspi.c | 0 .../mtd/spi-nor/{ => controllers}/nxp-spifi.c | 0 .../spi-nor/{ => controllers}/stm32-quadspi.c | 0 drivers/mtd/spi-nor/{spi-nor.c => core.c} | 311 +---------------- drivers/mtd/spi-nor/internals.h | 321 ++++++++++++++++++ 18 files changed, 446 insertions(+), 427 deletions(-) create mode 100644 drivers/mtd/spi-nor/controllers/Kconfig create mode 100644 drivers/mtd/spi-nor/controllers/Makefile rename drivers/mtd/spi-nor/{ => controllers}/aspeed-smc.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/atmel-quadspi.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/cadence-quadspi.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/fsl-quadspi.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/hisi-sfc.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/intel-spi-pci.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/intel-spi-platform.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/intel-spi.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/intel-spi.h (100%) rename drivers/mtd/spi-nor/{ => controllers}/mtk-quadspi.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/nxp-spifi.c (100%) rename drivers/mtd/spi-nor/{ => controllers}/stm32-quadspi.c (100%) rename drivers/mtd/spi-nor/{spi-nor.c => core.c} (91%) create mode 100644 drivers/mtd/spi-nor/internals.h diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig index 6cc9c929ff57..d4f9187100e2 100644 --- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig @@ -7,14 +7,6 @@ menuconfig MTD_SPI_NOR if MTD_SPI_NOR -config MTD_MT81xx_NOR - tristate "Mediatek MT81xx SPI NOR flash controller" - depends on HAS_IOMEM - help - This enables access to SPI NOR flash, using MT81xx SPI NOR flash - controller. This controller does not support generic SPI BUS, it only - supports SPI NOR Flash. - config MTD_SPI_NOR_USE_4K_SECTORS bool "Use small 4096 B erase sectors" default y @@ -29,104 +21,6 @@ config MTD_SPI_NOR_USE_4K_SECTORS Please note that some tools/drivers/filesystems may not work with 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). -config SPI_ASPEED_SMC - tristate "Aspeed flash controllers in SPI mode" - depends on ARCH_ASPEED || COMPILE_TEST - depends on HAS_IOMEM && OF - help - This enables support for the Firmware Memory controller (FMC) - in the Aspeed AST2500/AST2400 SoCs when attached to SPI NOR chips, - and support for the SPI flash memory controller (SPI) for - the host firmware. The implementation only supports SPI NOR. - -config SPI_ATMEL_QUADSPI - tristate "Atmel Quad SPI Controller" - depends on ARCH_AT91 || (ARM && COMPILE_TEST) - depends on OF && HAS_IOMEM - help - This enables support for the Quad SPI controller in master mode. - This driver does not support generic SPI. The implementation only - supports SPI NOR. - -config SPI_CADENCE_QUADSPI - tristate "Cadence Quad SPI controller" - depends on OF && (ARM || ARM64 || COMPILE_TEST) - help - Enable support for the Cadence Quad SPI Flash controller. - - Cadence QSPI is a specialized controller for connecting an SPI - Flash over 1/2/4-bit wide bus. Enable this option if you have a - device with a Cadence QSPI controller and want to access the - Flash as an MTD device. - -config SPI_FSL_QUADSPI - tristate "Freescale Quad SPI controller" - depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST - depends on HAS_IOMEM - help - This enables support for the Quad SPI controller in master mode. - This controller does not support generic SPI. It only supports - SPI NOR. - -config SPI_HISI_SFC - tristate "Hisilicon SPI-NOR Flash Controller(SFC)" - depends on ARCH_HISI || COMPILE_TEST - depends on HAS_IOMEM - help - This enables support for hisilicon SPI-NOR flash controller. - -config SPI_NXP_SPIFI - tristate "NXP SPI Flash Interface (SPIFI)" - depends on OF && (ARCH_LPC18XX || COMPILE_TEST) - depends on HAS_IOMEM - help - Enable support for the NXP LPC SPI Flash Interface controller. - - SPIFI is a specialized controller for connecting serial SPI - Flash. Enable this option if you have a device with a SPIFI - controller and want to access the Flash as a mtd device. - -config SPI_INTEL_SPI - tristate - -config SPI_INTEL_SPI_PCI - tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)" - depends on X86 && PCI - select SPI_INTEL_SPI - help - This enables PCI support for the Intel PCH/PCU SPI controller in - master mode. This controller is present in modern Intel hardware - and is used to hold BIOS and other persistent settings. Using - this driver it is possible to upgrade BIOS directly from Linux. - - Say N here unless you know what you are doing. Overwriting the - SPI flash may render the system unbootable. - - To compile this driver as a module, choose M here: the module - will be called intel-spi-pci. - -config SPI_INTEL_SPI_PLATFORM - tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)" - depends on X86 - select SPI_INTEL_SPI - help - This enables platform support for the Intel PCH/PCU SPI - controller in master mode. This controller is present in modern - Intel hardware and is used to hold BIOS and other persistent - settings. Using this driver it is possible to upgrade BIOS - directly from Linux. - - Say N here unless you know what you are doing. Overwriting the - SPI flash may render the system unbootable. - - To compile this driver as a module, choose M here: the module - will be called intel-spi-platform. - -config SPI_STM32_QUADSPI - tristate "STM32 Quad SPI controller" - depends on ARCH_STM32 || COMPILE_TEST - help - This enables support for the STM32 Quad SPI controller. - We only connect the NOR to this controller. +source "drivers/mtd/spi-nor/controllers/Kconfig" endif # MTD_SPI_NOR diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index f4c61d282abd..0d6c4967a445 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,13 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +spi-nor-objs := core.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o -obj-$(CONFIG_SPI_ASPEED_SMC) += aspeed-smc.o -obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o -obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o -obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o -obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o -obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o -obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o -obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o -obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o -obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o -obj-$(CONFIG_SPI_STM32_QUADSPI) += stm32-quadspi.o + +obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig new file mode 100644 index 000000000000..6356cbf465a4 --- /dev/null +++ b/drivers/mtd/spi-nor/controllers/Kconfig @@ -0,0 +1,107 @@ +config MTD_MT81xx_NOR + tristate "Mediatek MT81xx SPI NOR flash controller" + depends on HAS_IOMEM + help + This enables access to SPI NOR flash, using MT81xx SPI NOR flash + controller. This controller does not support generic SPI BUS, it only + supports SPI NOR Flash. + +config SPI_ASPEED_SMC + tristate "Aspeed flash controllers in SPI mode" + depends on ARCH_ASPEED || COMPILE_TEST + depends on HAS_IOMEM && OF + help + This enables support for the Firmware Memory controller (FMC) + in the Aspeed AST2500/AST2400 SoCs when attached to SPI NOR chips, + and support for the SPI flash memory controller (SPI) for + the host firmware. The implementation only supports SPI NOR. + +config SPI_ATMEL_QUADSPI + tristate "Atmel Quad SPI Controller" + depends on ARCH_AT91 || (ARM && COMPILE_TEST) + depends on OF && HAS_IOMEM + help + This enables support for the Quad SPI controller in master mode. + This driver does not support generic SPI. The implementation only + supports SPI NOR. + +config SPI_CADENCE_QUADSPI + tristate "Cadence Quad SPI controller" + depends on OF && (ARM || ARM64 || COMPILE_TEST) + help + Enable support for the Cadence Quad SPI Flash controller. + + Cadence QSPI is a specialized controller for connecting an SPI + Flash over 1/2/4-bit wide bus. Enable this option if you have a + device with a Cadence QSPI controller and want to access the + Flash as an MTD device. + +config SPI_FSL_QUADSPI + tristate "Freescale Quad SPI controller" + depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST + depends on HAS_IOMEM + help + This enables support for the Quad SPI controller in master mode. + This controller does not support generic SPI. It only supports + SPI NOR. + +config SPI_HISI_SFC + tristate "Hisilicon SPI-NOR Flash Controller(SFC)" + depends on ARCH_HISI || COMPILE_TEST + depends on HAS_IOMEM + help + This enables support for hisilicon SPI-NOR flash controller. + +config SPI_NXP_SPIFI + tristate "NXP SPI Flash Interface (SPIFI)" + depends on OF && (ARCH_LPC18XX || COMPILE_TEST) + depends on HAS_IOMEM + help + Enable support for the NXP LPC SPI Flash Interface controller. + + SPIFI is a specialized controller for connecting serial SPI + Flash. Enable this option if you have a device with a SPIFI + controller and want to access the Flash as a mtd device. + +config SPI_INTEL_SPI + tristate + +config SPI_INTEL_SPI_PCI + tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)" + depends on X86 && PCI + select SPI_INTEL_SPI + help + This enables PCI support for the Intel PCH/PCU SPI controller in + master mode. This controller is present in modern Intel hardware + and is used to hold BIOS and other persistent settings. Using + this driver it is possible to upgrade BIOS directly from Linux. + + Say N here unless you know what you are doing. Overwriting the + SPI flash may render the system unbootable. + + To compile this driver as a module, choose M here: the module + will be called intel-spi-pci. + +config SPI_INTEL_SPI_PLATFORM + tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)" + depends on X86 + select SPI_INTEL_SPI + help + This enables platform support for the Intel PCH/PCU SPI + controller in master mode. This controller is present in modern + Intel hardware and is used to hold BIOS and other persistent + settings. Using this driver it is possible to upgrade BIOS + directly from Linux. + + Say N here unless you know what you are doing. Overwriting the + SPI flash may render the system unbootable. + + To compile this driver as a module, choose M here: the module + will be called intel-spi-platform. + +config SPI_STM32_QUADSPI + tristate "STM32 Quad SPI controller" + depends on ARCH_STM32 || COMPILE_TEST + help + This enables support for the STM32 Quad SPI controller. + We only connect the NOR to this controller. diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile new file mode 100644 index 000000000000..0cb3384a32ac --- /dev/null +++ b/drivers/mtd/spi-nor/controllers/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_SPI_ASPEED_SMC) += aspeed-smc.o +obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o +obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o +obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o +obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o +obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o +obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o +obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o +obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o +obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o +obj-$(CONFIG_SPI_STM32_QUADSPI) += stm32-quadspi.o diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c similarity index 100% rename from drivers/mtd/spi-nor/aspeed-smc.c rename to drivers/mtd/spi-nor/controllers/aspeed-smc.c diff --git a/drivers/mtd/spi-nor/atmel-quadspi.c b/drivers/mtd/spi-nor/controllers/atmel-quadspi.c similarity index 100% rename from drivers/mtd/spi-nor/atmel-quadspi.c rename to drivers/mtd/spi-nor/controllers/atmel-quadspi.c diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c similarity index 100% rename from drivers/mtd/spi-nor/cadence-quadspi.c rename to drivers/mtd/spi-nor/controllers/cadence-quadspi.c diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/controllers/fsl-quadspi.c similarity index 100% rename from drivers/mtd/spi-nor/fsl-quadspi.c rename to drivers/mtd/spi-nor/controllers/fsl-quadspi.c diff --git a/drivers/mtd/spi-nor/hisi-sfc.c b/drivers/mtd/spi-nor/controllers/hisi-sfc.c similarity index 100% rename from drivers/mtd/spi-nor/hisi-sfc.c rename to drivers/mtd/spi-nor/controllers/hisi-sfc.c diff --git a/drivers/mtd/spi-nor/intel-spi-pci.c b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c similarity index 100% rename from drivers/mtd/spi-nor/intel-spi-pci.c rename to drivers/mtd/spi-nor/controllers/intel-spi-pci.c diff --git a/drivers/mtd/spi-nor/intel-spi-platform.c b/drivers/mtd/spi-nor/controllers/intel-spi-platform.c similarity index 100% rename from drivers/mtd/spi-nor/intel-spi-platform.c rename to drivers/mtd/spi-nor/controllers/intel-spi-platform.c diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c similarity index 100% rename from drivers/mtd/spi-nor/intel-spi.c rename to drivers/mtd/spi-nor/controllers/intel-spi.c diff --git a/drivers/mtd/spi-nor/intel-spi.h b/drivers/mtd/spi-nor/controllers/intel-spi.h similarity index 100% rename from drivers/mtd/spi-nor/intel-spi.h rename to drivers/mtd/spi-nor/controllers/intel-spi.h diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/controllers/mtk-quadspi.c similarity index 100% rename from drivers/mtd/spi-nor/mtk-quadspi.c rename to drivers/mtd/spi-nor/controllers/mtk-quadspi.c diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/controllers/nxp-spifi.c similarity index 100% rename from drivers/mtd/spi-nor/nxp-spifi.c rename to drivers/mtd/spi-nor/controllers/nxp-spifi.c diff --git a/drivers/mtd/spi-nor/stm32-quadspi.c b/drivers/mtd/spi-nor/controllers/stm32-quadspi.c similarity index 100% rename from drivers/mtd/spi-nor/stm32-quadspi.c rename to drivers/mtd/spi-nor/controllers/stm32-quadspi.c diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/core.c similarity index 91% rename from drivers/mtd/spi-nor/spi-nor.c rename to drivers/mtd/spi-nor/core.c index 34d3d632e53b..f8b7c8fbe960 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/core.c @@ -22,6 +22,8 @@ #include #include +#include "internals.h" + /* Define max times to check status register before we give up. */ /* @@ -36,267 +38,8 @@ */ #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) -#define SPI_NOR_MAX_ID_LEN 6 #define SPI_NOR_MAX_ADDR_WIDTH 4 -struct spi_nor_read_command { - u8 num_mode_clocks; - u8 num_wait_states; - u8 opcode; - enum spi_nor_protocol proto; -}; - -struct spi_nor_pp_command { - u8 opcode; - enum spi_nor_protocol proto; -}; - -enum spi_nor_read_command_index { - SNOR_CMD_READ, - SNOR_CMD_READ_FAST, - SNOR_CMD_READ_1_1_1_DTR, - - /* Dual SPI */ - SNOR_CMD_READ_1_1_2, - SNOR_CMD_READ_1_2_2, - SNOR_CMD_READ_2_2_2, - SNOR_CMD_READ_1_2_2_DTR, - - /* Quad SPI */ - SNOR_CMD_READ_1_1_4, - SNOR_CMD_READ_1_4_4, - SNOR_CMD_READ_4_4_4, - SNOR_CMD_READ_1_4_4_DTR, - - /* Octo SPI */ - SNOR_CMD_READ_1_1_8, - SNOR_CMD_READ_1_8_8, - SNOR_CMD_READ_8_8_8, - SNOR_CMD_READ_1_8_8_DTR, - - SNOR_CMD_READ_MAX -}; - -enum spi_nor_pp_command_index { - SNOR_CMD_PP, - - /* Quad SPI */ - SNOR_CMD_PP_1_1_4, - SNOR_CMD_PP_1_4_4, - SNOR_CMD_PP_4_4_4, - - /* Octo SPI */ - SNOR_CMD_PP_1_1_8, - SNOR_CMD_PP_1_8_8, - SNOR_CMD_PP_8_8_8, - - SNOR_CMD_PP_MAX -}; - -struct spi_nor_flash_parameter { - u64 size; - u32 page_size; - - struct spi_nor_hwcaps hwcaps; - struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; - struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; - - int (*quad_enable)(struct spi_nor *nor); -}; - -struct sfdp_parameter_header { - u8 id_lsb; - u8 minor; - u8 major; - u8 length; /* in double words */ - u8 parameter_table_pointer[3]; /* byte address */ - u8 id_msb; -}; - -#define SFDP_PARAM_HEADER_ID(p) (((p)->id_msb << 8) | (p)->id_lsb) -#define SFDP_PARAM_HEADER_PTP(p) \ - (((p)->parameter_table_pointer[2] << 16) | \ - ((p)->parameter_table_pointer[1] << 8) | \ - ((p)->parameter_table_pointer[0] << 0)) - -#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ -#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ - -#define SFDP_SIGNATURE 0x50444653U -#define SFDP_JESD216_MAJOR 1 -#define SFDP_JESD216_MINOR 0 -#define SFDP_JESD216A_MINOR 5 -#define SFDP_JESD216B_MINOR 6 - -struct sfdp_header { - u32 signature; /* Ox50444653U <=> "SFDP" */ - u8 minor; - u8 major; - u8 nph; /* 0-base number of parameter headers */ - u8 unused; - - /* Basic Flash Parameter Table. */ - struct sfdp_parameter_header bfpt_header; -}; - -/* Basic Flash Parameter Table */ - -/* - * JESD216 rev B defines a Basic Flash Parameter Table of 16 DWORDs. - * They are indexed from 1 but C arrays are indexed from 0. - */ -#define BFPT_DWORD(i) ((i) - 1) -#define BFPT_DWORD_MAX 16 - -/* The first version of JESB216 defined only 9 DWORDs. */ -#define BFPT_DWORD_MAX_JESD216 9 - -/* 1st DWORD. */ -#define BFPT_DWORD1_FAST_READ_1_1_2 BIT(16) -#define BFPT_DWORD1_ADDRESS_BYTES_MASK GENMASK(18, 17) -#define BFPT_DWORD1_ADDRESS_BYTES_3_ONLY (0x0UL << 17) -#define BFPT_DWORD1_ADDRESS_BYTES_3_OR_4 (0x1UL << 17) -#define BFPT_DWORD1_ADDRESS_BYTES_4_ONLY (0x2UL << 17) -#define BFPT_DWORD1_DTR BIT(19) -#define BFPT_DWORD1_FAST_READ_1_2_2 BIT(20) -#define BFPT_DWORD1_FAST_READ_1_4_4 BIT(21) -#define BFPT_DWORD1_FAST_READ_1_1_4 BIT(22) - -/* 5th DWORD. */ -#define BFPT_DWORD5_FAST_READ_2_2_2 BIT(0) -#define BFPT_DWORD5_FAST_READ_4_4_4 BIT(4) - -/* 11th DWORD. */ -#define BFPT_DWORD11_PAGE_SIZE_SHIFT 4 -#define BFPT_DWORD11_PAGE_SIZE_MASK GENMASK(7, 4) - -/* 15th DWORD. */ - -/* - * (from JESD216 rev B) - * Quad Enable Requirements (QER): - * - 000b: Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 - * reads based on instruction. DQ3/HOLD# functions are hold during - * instruction phase. - * - 001b: QE is bit 1 of status register 2. It is set via Write Status with - * two data bytes where bit 1 of the second byte is one. - * [...] - * Writing only one byte to the status register has the side-effect of - * clearing status register 2, including the QE bit. The 100b code is - * used if writing one byte to the status register does not modify - * status register 2. - * - 010b: QE is bit 6 of status register 1. It is set via Write Status with - * one data byte where bit 6 is one. - * [...] - * - 011b: QE is bit 7 of status register 2. It is set via Write status - * register 2 instruction 3Eh with one data byte where bit 7 is one. - * [...] - * The status register 2 is read using instruction 3Fh. - * - 100b: QE is bit 1 of status register 2. It is set via Write Status with - * two data bytes where bit 1 of the second byte is one. - * [...] - * In contrast to the 001b code, writing one byte to the status - * register does not modify status register 2. - * - 101b: QE is bit 1 of status register 2. Status register 1 is read using - * Read Status instruction 05h. Status register2 is read using - * instruction 35h. QE is set via Writ Status instruction 01h with - * two data bytes where bit 1 of the second byte is one. - * [...] - */ -#define BFPT_DWORD15_QER_MASK GENMASK(22, 20) -#define BFPT_DWORD15_QER_NONE (0x0UL << 20) /* Micron */ -#define BFPT_DWORD15_QER_SR2_BIT1_BUGGY (0x1UL << 20) -#define BFPT_DWORD15_QER_SR1_BIT6 (0x2UL << 20) /* Macronix */ -#define BFPT_DWORD15_QER_SR2_BIT7 (0x3UL << 20) -#define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) -#define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ - -struct sfdp_bfpt { - u32 dwords[BFPT_DWORD_MAX]; -}; - -/** - * struct spi_nor_fixups - SPI NOR fixup hooks - * @post_bfpt: called after the BFPT table has been parsed - * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs - * that do not support RDSFDP). Typically used to tweak various - * parameters that could not be extracted by other means (i.e. - * when information provided by the SFDP/flash_info tables are - * incomplete or wrong). - * - * Those hooks can be used to tweak the SPI NOR configuration when the SFDP - * table is broken or not available. - */ -struct spi_nor_fixups { - int (*post_bfpt)(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params); - int (*post_sfdp)(struct spi_nor *nor, - struct spi_nor_flash_parameter *params); -}; - -struct flash_info { - char *name; - - /* - * This array stores the ID bytes. - * The first three bytes are the JEDIC ID. - * JEDEC ID zero means "no ID" (mostly older chips). - */ - u8 id[SPI_NOR_MAX_ID_LEN]; - u8 id_len; - - /* The size listed here is what works with SPINOR_OP_SE, which isn't - * necessarily called a "sector" by the vendor. - */ - unsigned sector_size; - u16 n_sectors; - - u16 page_size; - u16 addr_width; - - u16 flags; -#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */ -#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */ -#define SST_WRITE BIT(2) /* use SST byte programming */ -#define SPI_NOR_NO_FR BIT(3) /* Can't do fastread */ -#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works uniformly */ -#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */ -#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */ -#define USE_FSR BIT(7) /* use flag status register */ -#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR */ -#define SPI_NOR_HAS_TB BIT(9) /* - * Flash SR has Top/Bottom (TB) protect - * bit. Must be used with - * SPI_NOR_HAS_LOCK. - */ -#define SPI_NOR_XSR_RDY BIT(10) /* - * S3AN flashes have specific opcode to - * read the status register. - * Flags SPI_NOR_XSR_RDY and SPI_S3AN - * use the same bit as one implies the - * other, but we will get rid of - * SPI_S3AN soon. - */ -#define SPI_S3AN BIT(10) /* - * Xilinx Spartan 3AN In-System Flash - * (MFR cannot be used for probing - * because it has the same value as - * ATMEL flashes) - */ -#define SPI_NOR_4B_OPCODES BIT(11) /* - * Use dedicated 4byte address op codes - * to support memory size above 128Mib. - */ -#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */ -#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */ -#define USE_CLSR BIT(14) /* use CLSR command */ - - /* Part specific fixup hooks. */ - const struct spi_nor_fixups *fixups; -}; - #define JEDEC_MFR(info) ((info)->id[0]) /* @@ -1617,56 +1360,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) return 0; } -/* Used when the "_ext_id" is two bytes at most */ -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff, \ - ((_ext_id) >> 8) & 0xff, \ - (_ext_id) & 0xff, \ - }, \ - .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .flags = (_flags), - -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff, \ - ((_ext_id) >> 16) & 0xff, \ - ((_ext_id) >> 8) & 0xff, \ - (_ext_id) & 0xff, \ - }, \ - .id_len = 6, \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .flags = (_flags), - -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = (_page_size), \ - .addr_width = (_addr_width), \ - .flags = (_flags), - -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff \ - }, \ - .id_len = 3, \ - .sector_size = (8*_page_size), \ - .n_sectors = (_n_sectors), \ - .page_size = _page_size, \ - .addr_width = 3, \ - .flags = SPI_NOR_NO_FR | SPI_S3AN, - static int gd25q256_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h new file mode 100644 index 000000000000..cc06fed99f49 --- /dev/null +++ b/drivers/mtd/spi-nor/internals.h @@ -0,0 +1,321 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#ifndef __LINUX_MTD_SPI_NOR_INTERNALS_H +#define __LINUX_MTD_SPI_NOR_INTERNALS_H + +#define SPI_NOR_MAX_ID_LEN 6 + +struct spi_nor_read_command { + u8 num_mode_clocks; + u8 num_wait_states; + u8 opcode; + enum spi_nor_protocol proto; +}; + +struct spi_nor_pp_command { + u8 opcode; + enum spi_nor_protocol proto; +}; + +enum spi_nor_read_command_index { + SNOR_CMD_READ, + SNOR_CMD_READ_FAST, + SNOR_CMD_READ_1_1_1_DTR, + + /* Dual SPI */ + SNOR_CMD_READ_1_1_2, + SNOR_CMD_READ_1_2_2, + SNOR_CMD_READ_2_2_2, + SNOR_CMD_READ_1_2_2_DTR, + + /* Quad SPI */ + SNOR_CMD_READ_1_1_4, + SNOR_CMD_READ_1_4_4, + SNOR_CMD_READ_4_4_4, + SNOR_CMD_READ_1_4_4_DTR, + + /* Octo SPI */ + SNOR_CMD_READ_1_1_8, + SNOR_CMD_READ_1_8_8, + SNOR_CMD_READ_8_8_8, + SNOR_CMD_READ_1_8_8_DTR, + + SNOR_CMD_READ_MAX +}; + +enum spi_nor_pp_command_index { + SNOR_CMD_PP, + + /* Quad SPI */ + SNOR_CMD_PP_1_1_4, + SNOR_CMD_PP_1_4_4, + SNOR_CMD_PP_4_4_4, + + /* Octo SPI */ + SNOR_CMD_PP_1_1_8, + SNOR_CMD_PP_1_8_8, + SNOR_CMD_PP_8_8_8, + + SNOR_CMD_PP_MAX +}; + +struct spi_nor_flash_parameter { + u64 size; + u32 page_size; + + struct spi_nor_hwcaps hwcaps; + struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; + struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; + + int (*quad_enable)(struct spi_nor *nor); +}; + +struct sfdp_parameter_header { + u8 id_lsb; + u8 minor; + u8 major; + u8 length; /* in double words */ + u8 parameter_table_pointer[3]; /* byte address */ + u8 id_msb; +}; + +#define SFDP_PARAM_HEADER_ID(p) (((p)->id_msb << 8) | (p)->id_lsb) +#define SFDP_PARAM_HEADER_PTP(p) \ + (((p)->parameter_table_pointer[2] << 16) | \ + ((p)->parameter_table_pointer[1] << 8) | \ + ((p)->parameter_table_pointer[0] << 0)) + +#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ +#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ + +#define SFDP_SIGNATURE 0x50444653U +#define SFDP_JESD216_MAJOR 1 +#define SFDP_JESD216_MINOR 0 +#define SFDP_JESD216A_MINOR 5 +#define SFDP_JESD216B_MINOR 6 + +struct sfdp_header { + u32 signature; /* Ox50444653U <=> "SFDP" */ + u8 minor; + u8 major; + u8 nph; /* 0-base number of parameter headers */ + u8 unused; + + /* Basic Flash Parameter Table. */ + struct sfdp_parameter_header bfpt_header; +}; + +/* Basic Flash Parameter Table */ + +/* + * JESD216 rev B defines a Basic Flash Parameter Table of 16 DWORDs. + * They are indexed from 1 but C arrays are indexed from 0. + */ +#define BFPT_DWORD(i) ((i) - 1) +#define BFPT_DWORD_MAX 16 + +/* The first version of JESB216 defined only 9 DWORDs. */ +#define BFPT_DWORD_MAX_JESD216 9 + +/* 1st DWORD. */ +#define BFPT_DWORD1_FAST_READ_1_1_2 BIT(16) +#define BFPT_DWORD1_ADDRESS_BYTES_MASK GENMASK(18, 17) + +#define BFPT_DWORD1_ADDRESS_BYTES_3_ONLY (0x0UL << 17) +#define BFPT_DWORD1_ADDRESS_BYTES_3_OR_4 (0x1UL << 17) +#define BFPT_DWORD1_ADDRESS_BYTES_4_ONLY (0x2UL << 17) +#define BFPT_DWORD1_DTR BIT(19) +#define BFPT_DWORD1_FAST_READ_1_2_2 BIT(20) +#define BFPT_DWORD1_FAST_READ_1_4_4 BIT(21) +#define BFPT_DWORD1_FAST_READ_1_1_4 BIT(22) + +/* 5th DWORD. */ +#define BFPT_DWORD5_FAST_READ_2_2_2 BIT(0) +#define BFPT_DWORD5_FAST_READ_4_4_4 BIT(4) + +/* 11th DWORD. */ +#define BFPT_DWORD11_PAGE_SIZE_SHIFT 4 +#define BFPT_DWORD11_PAGE_SIZE_MASK GENMASK(7, 4) + +/* 15th DWORD. */ + +/* + * (from JESD216 rev B) + * Quad Enable Requirements (QER): + * - 000b: Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 + * reads based on instruction. DQ3/HOLD# functions are hold during + * instruction phase. + * - 001b: QE is bit 1 of status register 2. It is set via Write Status with + * two data bytes where bit 1 of the second byte is one. + * [...] + * Writing only one byte to the status register has the side-effect of + * clearing status register 2, including the QE bit. The 100b code is + * used if writing one byte to the status register does not modify + * status register 2. + * - 010b: QE is bit 6 of status register 1. It is set via Write Status with + * one data byte where bit 6 is one. + * [...] + * - 011b: QE is bit 7 of status register 2. It is set via Write status + * register 2 instruction 3Eh with one data byte where bit 7 is one. + * [...] + * The status register 2 is read using instruction 3Fh. + * - 100b: QE is bit 1 of status register 2. It is set via Write Status with + * two data bytes where bit 1 of the second byte is one. + * [...] + * In contrast to the 001b code, writing one byte to the status + * register does not modify status register 2. + * - 101b: QE is bit 1 of status register 2. Status register 1 is read using + * Read Status instruction 05h. Status register2 is read using + * instruction 35h. QE is set via Writ Status instruction 01h with + * two data bytes where bit 1 of the second byte is one. + * [...] + */ +#define BFPT_DWORD15_QER_MASK GENMASK(22, 20) +#define BFPT_DWORD15_QER_NONE (0x0UL << 20) /* Micron */ +#define BFPT_DWORD15_QER_SR2_BIT1_BUGGY (0x1UL << 20) +#define BFPT_DWORD15_QER_SR1_BIT6 (0x2UL << 20) /* Macronix */ +#define BFPT_DWORD15_QER_SR2_BIT7 (0x3UL << 20) +#define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) +#define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ + +struct sfdp_bfpt { + u32 dwords[BFPT_DWORD_MAX]; +}; + +/** + * struct spi_nor_fixups - SPI NOR fixup hooks + * @post_bfpt: called after the BFPT table has been parsed + * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs + * that do not support RDSFDP). Typically used to tweak various + * parameters that could not be extracted by other means (i.e. + * when information provided by the SFDP/flash_info tables are + * incomplete or wrong). + * + * Those hooks can be used to tweak the SPI NOR configuration when the SFDP + * table is broken or not available. + */ +struct spi_nor_fixups { + int (*post_bfpt)(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params); + int (*post_sfdp)(struct spi_nor *nor, + struct spi_nor_flash_parameter *params); +}; + +struct flash_info { + char *name; + + /* + * This array stores the ID bytes. + * The first three bytes are the JEDIC ID. + * JEDEC ID zero means "no ID" (mostly older chips). + */ + u8 id[SPI_NOR_MAX_ID_LEN]; + u8 id_len; + + /* The size listed here is what works with SPINOR_OP_SE, which isn't + * necessarily called a "sector" by the vendor. + */ + unsigned sector_size; + u16 n_sectors; + + u16 page_size; + u16 addr_width; + + u16 flags; +#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */ +#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */ +#define SST_WRITE BIT(2) /* use SST byte programming */ +#define SPI_NOR_NO_FR BIT(3) /* Can't do fastread */ +#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works uniformly */ +#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */ +#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */ +#define USE_FSR BIT(7) /* use flag status register */ +#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR */ +#define SPI_NOR_HAS_TB BIT(9) /* + * Flash SR has Top/Bottom (TB) protect + * bit. Must be used with + * SPI_NOR_HAS_LOCK. + */ +#define SPI_NOR_XSR_RDY BIT(10) /* + * S3AN flashes have specific opcode to + * read the status register. + * Flags SPI_NOR_XSR_RDY and SPI_S3AN + * use the same bit as one implies the + * other, but we will get rid of + * SPI_S3AN soon. + */ +#define SPI_S3AN BIT(10) /* + * Xilinx Spartan 3AN In-System Flash + * (MFR cannot be used for probing + * because it has the same value as + * ATMEL flashes) + */ +#define SPI_NOR_4B_OPCODES BIT(11) /* + * Use dedicated 4byte address op codes + * to support memory size above 128Mib. + */ +#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */ +#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */ +#define USE_CLSR BIT(14) /* use CLSR command */ + + /* Part specific fixup hooks. */ + const struct spi_nor_fixups *fixups; +}; + +/* Used when the "_ext_id" is two bytes at most */ +#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff, \ + ((_ext_id) >> 8) & 0xff, \ + (_ext_id) & 0xff, \ + }, \ + .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = 256, \ + .flags = (_flags), + +#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff, \ + ((_ext_id) >> 16) & 0xff, \ + ((_ext_id) >> 8) & 0xff, \ + (_ext_id) & 0xff, \ + }, \ + .id_len = 6, \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = 256, \ + .flags = (_flags), + +#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = (_page_size), \ + .addr_width = (_addr_width), \ + .flags = (_flags), + +#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff \ + }, \ + .id_len = 3, \ + .sector_size = (8*_page_size), \ + .n_sectors = (_n_sectors), \ + .page_size = _page_size, \ + .addr_width = 3, \ + .flags = SPI_NOR_NO_FR | SPI_S3AN, + +#endif /* __LINUX_MTD_SPI_NOR_INTERNALS_H */ From patchwork Fri Dec 7 09:26:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009266 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="OBEYoMum"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6bT1J5Zz9s8F for ; Fri, 7 Dec 2018 20:28:37 +1100 (AEDT) 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=kMV9p2hRd1rTxO3o7nFXlCF5NVFnd1CTviCmrmH9CYo=; b=OBEYoMumMuxdxhP4gvua++MGBb gULq9HheqXfUKF7U7LwMDXcYXx6mvIopN/62xvIa8eWokFJ7tPUR9WRur1ni0vuAsdHRCrCDPiMDM f/y6BTp2mVR3CG6ccWRjVfZmRbXwkyZazHOuBgqX/lZVqCTHfZt5N2+e+eJ1xabxRLnIO6iaxq+Ss UeslndXaMwUhsbE2hF3BcqDUetYqmYafqcc8npT3FXj2GNohWf9GZKJd4LttbvGaaEApFG0ivbR5T +1CoXNY0kA3pqz0wlJNqy8xReK1lJ3I9LyURKa0HT4EVhysGvFkbcJ7VbSClpTfIAlMEdb2qfzob0 1YwqvvEQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQz-0002bt-V6; Fri, 07 Dec 2018 09:28:34 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-00010A-Bq for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:21 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 3EA7520DD3; Fri, 7 Dec 2018 10:26:51 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 7062C20E0C; Fri, 7 Dec 2018 10:26:40 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 13/34] mtd: spi-nor: Add the concept of SPI NOR manufacturer driver Date: Fri, 7 Dec 2018 10:26:16 +0100 Message-Id: <20181207092637.18687-14-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_495668_12E1C6C3 X-CRM114-Status: GOOD ( 20.13 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Declare a spi_nor_manufacturer struct and add basic building blocks to move manufacturer specific code outside of the core. We also rename spi-nor.c into spi-nor-core.c and adjust the Makefile to be able to create spi-nor.o by linking the core and manufacturer drivers together. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/core.c | 82 +++++++++++++++++++++++++++------ drivers/mtd/spi-nor/internals.h | 14 ++++++ include/linux/mtd/spi-nor.h | 8 ++++ 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index f8b7c8fbe960..8efd0490d2a0 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1722,6 +1722,23 @@ static const struct flash_info spi_nor_ids[] = { { }, }; +static const struct spi_nor_manufacturer *manufacturers[0]; + +static const struct flash_info * +spi_nor_search_part_by_id(const struct flash_info *parts, unsigned int nparts, + const u8 *id) +{ + unsigned int i; + + for (i = 0; i < nparts; i++) { + if (parts[i].id_len && + !memcmp(parts[i].id, id, parts[i].id_len)) + return &parts[i]; + } + + return NULL; +} + static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) { int tmp; @@ -1734,13 +1751,21 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) return ERR_PTR(tmp); } - for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { - info = &spi_nor_ids[tmp]; - if (info->id_len) { - if (!memcmp(info->id, id, info->id_len)) - return &spi_nor_ids[tmp]; + for (tmp = 0; tmp < ARRAY_SIZE(manufacturers); tmp++) { + info = spi_nor_search_part_by_id(manufacturers[tmp]->parts, + manufacturers[tmp]->nparts, + id); + if (info) { + nor->manufacturer = manufacturers[tmp]; + return info; } } + + info = spi_nor_search_part_by_id(spi_nor_ids, + ARRAY_SIZE(spi_nor_ids) - 1, id); + if (info) + return info; + dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", id[0], id[1], id[2]); return ERR_PTR(-ENODEV); @@ -2334,9 +2359,22 @@ spi_nor_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_bfpt *bfpt, struct spi_nor_flash_parameter *params) { - if (nor->info->fixups && nor->info->fixups->post_bfpt) - return nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, - params); + int ret; + + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->post_bfpt) { + ret = nor->manufacturer->fixups->post_bfpt(nor, bfpt_header, + bfpt, params); + if (ret) + return ret; + } + + if (nor->info->fixups && nor->info->fixups->post_bfpt) { + ret = nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, + params); + if (ret) + return ret; + } return 0; } @@ -3426,6 +3464,10 @@ static int spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->post_sfdp) + return nor->manufacturer->fixups->post_sfdp(nor, params); + switch (JEDEC_MFR(nor->info)) { case SNOR_MFR_ATMEL: atmel_post_sfdp_fixups(nor); @@ -3481,15 +3523,25 @@ static int spi_nor_post_sfdp_fixups(struct spi_nor *nor, return ret; } -static const struct flash_info *spi_nor_match_id(const char *name) +static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, + const char *name) { - const struct flash_info *id = spi_nor_ids; + unsigned int i, j; - while (id->name) { - if (!strcmp(name, id->name)) - return id; - id++; + for (i = 0; i < ARRAY_SIZE(spi_nor_ids) - 1; i++) { + if (!strcmp(name, spi_nor_ids[i].name)) + return &spi_nor_ids[i]; } + + for (i = 0; i < ARRAY_SIZE(manufacturers); i++) { + for (j = 0; j < manufacturers[i]->nparts; j++) { + if (!strcmp(name, manufacturers[i]->parts[j].name)) { + nor->manufacturer = manufacturers[i]; + return &manufacturers[i]->parts[j]; + } + } + } + return NULL; } @@ -3514,7 +3566,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->write_proto = SNOR_PROTO_1_1_1; if (name) - info = spi_nor_match_id(name); + info = spi_nor_match_id(nor, name); /* Try to auto-detect if chip name wasn't specified or not found */ if (!info) info = spi_nor_read_id(nor); diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index cc06fed99f49..c442d0bfa21a 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -318,4 +318,18 @@ struct flash_info { .addr_width = 3, \ .flags = SPI_NOR_NO_FR | SPI_S3AN, +/** + * struct spi_nor_manufacturer - SPI NOR manufacturer object + * @name: manufacturer name + * @parts: array of parts supported by this manufacturer + * @nparts: number of entries in the parts array + * @fixups: hooks called at various points in time during spi_nor_scan() + */ +struct spi_nor_manufacturer { + const char *name; + const struct flash_info *parts; + unsigned int nparts; + const struct spi_nor_fixups *fixups; +}; + #endif /* __LINUX_MTD_SPI_NOR_INTERNALS_H */ diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 8c64f1dcd35e..44ab116ce3d9 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -332,12 +332,19 @@ struct spi_nor_erase_map { */ struct flash_info; +/** + * struct flash_info - Forward declaration of a structure used internally by + * the core and manufacturer drivers + */ +struct spi_nor_manufacturer; + /** * struct spi_nor - Structure for defining a the SPI NOR layer * @mtd: point to a mtd_info structure * @lock: the lock for the read/write/erase/lock/unlock operations * @dev: point to a spi device, or a spi nor controller device. * @info: spi-nor part JDEC MFR id and other info + * @manufacturer: spi-nor manufacturer * @page_size: the page size of the SPI NOR * @addr_width: number of address bytes * @erase_opcode: the opcode for erasing a sector @@ -376,6 +383,7 @@ struct spi_nor { struct mutex lock; struct device *dev; const struct flash_info *info; + const struct spi_nor_manufacturer *manufacturer; u32 page_size; u8 addr_width; u8 erase_opcode; From patchwork Fri Dec 7 09:26:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009264 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="tzgGxlkg"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6bD0ZHdz9s3q for ; Fri, 7 Dec 2018 20:28:24 +1100 (AEDT) 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=2TxuU1igHpwGBtcsBMyfXyEOETBnGsihMwhuGuZ8zO0=; b=tzgGxlkgsn6nN0rp7Ov8aJSe52 cP+WuRXW/039mqMC3w/g41qymWDi9mKqiFd5PEX3euxZZGzt5eV2E42+LAxYlDjJo/Pl42wv15N2V WjDPy4TG7ByotqA5/T/LsInJLlw8hNPGIEkCwV0dzZa11r5zqASQ1DxEyhp9hd7Hq3F10hQBChsDN 9MRmagbGjmlr1yiw54ThEvNIPRZToVUrf/wfAWy+2BfmMkFVP27PeVplpBVFcPtZh7ijJ+EYipl9R UbR5rEhXe6hfg4tx9z4Uo8ECkcW46k+BI2JUBiplmqrJi86X4/KBKoOmDboZDKV3HMnqsJsSq4dqU rSlQYXiQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQk-0002P9-Tz; Fri, 07 Dec 2018 09:28:18 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-00010C-Br for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:21 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 542B320DDA; Fri, 7 Dec 2018 10:26:51 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id A698420E1F; Fri, 7 Dec 2018 10:26:40 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 14/34] mtd: spi-nor: Stop prefixing generic functions with a manufacturer name Date: Fri, 7 Dec 2018 10:26:17 +0100 Message-Id: <20181207092637.18687-15-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_486440_604C4BD5 X-CRM114-Status: GOOD ( 18.25 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Most quad_enable, set_4byte() and locking functions are manufacturer agnostic. Replace the manufacturer prefix by something describing more precisely what those functions do. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/core.c | 104 ++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 8efd0490d2a0..f3c8e4ac1158 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -220,7 +220,7 @@ static int set_4byte(struct spi_nor *nor, bool enable) return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1); } -static int s3an_sr_ready(struct spi_nor *nor) +static int spi_nor_xsr_ready(struct spi_nor *nor) { int ret; u8 val; @@ -281,7 +281,7 @@ static int spi_nor_ready(struct spi_nor *nor) int sr, fsr; if (nor->flags & SNOR_F_READY_XSR_RDY) - sr = s3an_sr_ready(nor); + sr = spi_nor_xsr_ready(nor); else sr = spi_nor_sr_ready(nor); if (sr < 0) @@ -797,8 +797,8 @@ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask) return ((ret & mask) != (status_new & mask)) ? -EIO : 0; } -static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, - uint64_t *len) +static void get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs, + uint64_t *len) { struct mtd_info *mtd = &nor->mtd; u8 mask = SR_BP2 | SR_BP1 | SR_BP0; @@ -823,8 +823,8 @@ static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, * Return 1 if the entire region is locked (if @locked is true) or unlocked (if * @locked is false); 0 otherwise */ -static int stm_check_lock_status_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, - u8 sr, bool locked) +static int check_lock_status_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, + u8 sr, bool locked) { loff_t lock_offs; uint64_t lock_len; @@ -832,7 +832,7 @@ static int stm_check_lock_status_sr(struct spi_nor *nor, loff_t ofs, uint64_t le if (!len) return 1; - stm_get_locked_range(nor, sr, &lock_offs, &lock_len); + get_locked_range_sr(nor, sr, &lock_offs, &lock_len); if (locked) /* Requested range is a sub-range of locked range */ @@ -842,16 +842,14 @@ static int stm_check_lock_status_sr(struct spi_nor *nor, loff_t ofs, uint64_t le return (ofs >= lock_offs + lock_len) || (ofs + len <= lock_offs); } -static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, - u8 sr) +static int is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, u8 sr) { - return stm_check_lock_status_sr(nor, ofs, len, sr, true); + return check_lock_status_sr(nor, ofs, len, sr, true); } -static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, - u8 sr) +static int is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, u8 sr) { - return stm_check_lock_status_sr(nor, ofs, len, sr, false); + return check_lock_status_sr(nor, ofs, len, sr, false); } /* @@ -886,7 +884,7 @@ static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, * * Returns negative on errors, 0 on success. */ -static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) { struct mtd_info *mtd = &nor->mtd; int status_old, status_new; @@ -901,16 +899,16 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) return status_old; /* If nothing in our range is unlocked, we don't need to do anything */ - if (stm_is_locked_sr(nor, ofs, len, status_old)) + if (is_locked_sr(nor, ofs, len, status_old)) return 0; /* If anything below us is unlocked, we can't use 'bottom' protection */ - if (!stm_is_locked_sr(nor, 0, ofs, status_old)) + if (!is_locked_sr(nor, 0, ofs, status_old)) can_be_bottom = false; /* If anything above us is unlocked, we can't use 'top' protection */ - if (!stm_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len), - status_old)) + if (!is_locked_sr(nor, ofs + len, mtd->size - (ofs + len), + status_old)) can_be_top = false; if (!can_be_bottom && !can_be_top) @@ -962,11 +960,11 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) } /* - * Unlock a region of the flash. See stm_lock() for more info + * Unlock a region of the flash. See sr_lock() for more info * * Returns negative on errors, 0 on success. */ -static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) { struct mtd_info *mtd = &nor->mtd; int status_old, status_new; @@ -981,16 +979,16 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) return status_old; /* If nothing in our range is locked, we don't need to do anything */ - if (stm_is_unlocked_sr(nor, ofs, len, status_old)) + if (is_unlocked_sr(nor, ofs, len, status_old)) return 0; /* If anything below us is locked, we can't use 'top' protection */ - if (!stm_is_unlocked_sr(nor, 0, ofs, status_old)) + if (!is_unlocked_sr(nor, 0, ofs, status_old)) can_be_top = false; /* If anything above us is locked, we can't use 'bottom' protection */ - if (!stm_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len), - status_old)) + if (!is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len), + status_old)) can_be_bottom = false; if (!can_be_bottom && !can_be_top) @@ -1045,13 +1043,13 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) } /* - * Check if a region of the flash is (completely) locked. See stm_lock() for + * Check if a region of the flash is (completely) locked. See sr_lock() for * more info. * * Returns 1 if entire region is locked, 0 if any portion is unlocked, and * negative on errors. */ -static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int sr_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) { int status; @@ -1059,13 +1057,13 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) if (status < 0) return status; - return stm_is_locked_sr(nor, ofs, len, status); + return is_locked_sr(nor, ofs, len, status); } -static const struct spi_nor_locking_ops stm_locking_ops = { - .lock = stm_lock, - .unlock = stm_unlock, - .is_locked = stm_is_locked, +static const struct spi_nor_locking_ops sr_locking_ops = { + .lock = sr_lock, + .unlock = sr_unlock, + .is_locked = sr_is_locked, }; static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) @@ -1148,7 +1146,7 @@ static int no_quad_enable(struct spi_nor *nor) } /** - * macronix_quad_enable() - set QE bit in Status Register. + * sr1_bit6_quad_enable() - set QE bit in Status Register. * @nor: pointer to a 'struct spi_nor' * * Set the Quad Enable (QE) bit in the Status Register. @@ -1157,7 +1155,7 @@ static int no_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int macronix_quad_enable(struct spi_nor *nor) +static int sr1_bit6_quad_enable(struct spi_nor *nor) { int ret, val; @@ -1177,7 +1175,7 @@ static int macronix_quad_enable(struct spi_nor *nor) ret = read_sr(nor); if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { - dev_err(nor->dev, "Macronix Quad bit not set\n"); + dev_err(nor->dev, "QE bit not set\n"); return -EINVAL; } @@ -1185,7 +1183,7 @@ static int macronix_quad_enable(struct spi_nor *nor) } /** - * spansion_quad_enable() - set QE bit in Configuraiton Register. + * legacy_quad_enable() - set QE bit in Configuraiton Register. * @nor: pointer to a 'struct spi_nor' * * Set the Quad Enable (QE) bit in the Configuration Register. @@ -1207,7 +1205,7 @@ static int macronix_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int spansion_quad_enable(struct spi_nor *nor) +static int legacy_quad_enable(struct spi_nor *nor) { u8 sr_cr[2] = {0, CR_QUAD_EN_SPAN}; int ret; @@ -1227,7 +1225,7 @@ static int spansion_quad_enable(struct spi_nor *nor) } /** - * spansion_no_read_cr_quad_enable() - set QE bit in Configuration Register. + * sr2_bit1_no_read_quad_enable() - set QE bit in Configuration Register. * @nor: pointer to a 'struct spi_nor' * * Set the Quad Enable (QE) bit in the Configuration Register. @@ -1239,7 +1237,7 @@ static int spansion_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int spansion_no_read_cr_quad_enable(struct spi_nor *nor) +static int sr2_bit1_no_read_quad_enable(struct spi_nor *nor) { u8 sr_cr[2]; int ret; @@ -1257,7 +1255,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor) } /** - * spansion_read_cr_quad_enable() - set QE bit in Configuration Register. + * sr2_bit1_read_quad_enable() - set QE bit in Configuration Register. * @nor: pointer to a 'struct spi_nor' * * Set the Quad Enable (QE) bit in the Configuration Register. @@ -1269,7 +1267,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int spansion_read_cr_quad_enable(struct spi_nor *nor) +static int sr2_bit1_read_quad_enable(struct spi_nor *nor) { struct device *dev = nor->dev; u8 sr_cr[2]; @@ -1363,7 +1361,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) static int gd25q256_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { - params->quad_enable = macronix_quad_enable; + params->quad_enable = sr1_bit6_quad_enable; return 0; } @@ -2548,11 +2546,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, case BFPT_DWORD15_QER_SR2_BIT1_BUGGY: case BFPT_DWORD15_QER_SR2_BIT1_NO_RD: - params->quad_enable = spansion_no_read_cr_quad_enable; + params->quad_enable = sr2_bit1_no_read_quad_enable; break; case BFPT_DWORD15_QER_SR1_BIT6: - params->quad_enable = macronix_quad_enable; + params->quad_enable = sr1_bit6_quad_enable; break; case BFPT_DWORD15_QER_SR2_BIT7: @@ -2560,7 +2558,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, break; case BFPT_DWORD15_QER_SR2_BIT1: - params->quad_enable = spansion_read_cr_quad_enable; + params->quad_enable = sr2_bit1_read_quad_enable; break; default: @@ -3326,18 +3324,18 @@ void spi_nor_restore(struct spi_nor *nor) } EXPORT_SYMBOL_GPL(spi_nor_restore); -static int macronix_set_4byte(struct spi_nor *nor, bool enable) +static int en4_ex4_set_4byte(struct spi_nor *nor, bool enable) { return nor->write_reg(nor, enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B, NULL, 0); } -static int st_micron_set_4byte(struct spi_nor *nor, bool enable) +static int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable) { int ret; write_enable(nor); - ret = macronix_set_4byte(nor, enable); + ret = en4_ex4_set_4byte(nor, enable); write_disable(nor); return ret; @@ -3347,7 +3345,7 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable) { int ret; - ret = macronix_set_4byte(nor, enable); + ret = en4_ex4_set_4byte(nor, enable); if (ret || enable) return ret; @@ -3369,14 +3367,14 @@ static void st_micron_post_sfdp_fixups(struct spi_nor *nor) { /* All ST/Micron NORs support the unlock/lock operations. */ nor->flags |= SNOR_F_HAS_LOCK; - nor->set_4byte = st_micron_set_4byte; + nor->set_4byte = en4_ex4_wen_set_4byte; nor->quad_enable = no_quad_enable; } static void macronix_post_sfdp_fixups(struct spi_nor *nor) { - nor->set_4byte = macronix_set_4byte; - nor->quad_enable = macronix_quad_enable; + nor->set_4byte = en4_ex4_set_4byte; + nor->quad_enable = sr1_bit6_quad_enable; } static void winbond_post_sfdp_fixups(struct spi_nor *nor) @@ -3669,7 +3667,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->flags |= SNOR_F_HAS_LOCK; /* Kept only for backward compatibility purpose. */ - nor->quad_enable = spansion_quad_enable; + nor->quad_enable = legacy_quad_enable; /* * Post SFDP fixups. Has to be called before spi_nor_setup() because @@ -3688,7 +3686,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, * pick the default ones. */ if (nor->flags & SNOR_F_HAS_LOCK && !nor->locking_ops) - nor->locking_ops = &stm_locking_ops; + nor->locking_ops = &sr_locking_ops; if (nor->locking_ops) { mtd->_lock = spi_nor_lock; From patchwork Fri Dec 7 09:26:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009269 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="kXVCwL5N"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6ct1pl6z9s3q for ; Fri, 7 Dec 2018 20:29:50 +1100 (AEDT) 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=li0gdiYthPT3c27Qkfm0Azr81ZHeNiFg3UjB0YO4Mwg=; b=kXVCwL5NQUAUr7OzAZ1dwUEZST IBPkSoxtws6URWxio/I54tYrn1AiKWRSgS+BIyKLccBiEJ9NemGqaFqqkJBULlQ22RvW09zT2rc+Z ZNmg3CLA7qq1/HTun4m4mhzhUlDHpU4p4JAYdpcKd+L5pxKM/aLT5ujlwICMGjz2sQiMu4coGXYoA 10mEYPBUkSiIxNteZeJ9vw4WnFm2H30pmJKWBMrmIU5tDwSU9itOEyXGvPwZUpfNQB7xF3Gim7MJY 2obKOcrJAS3orl6FpI9lxUTBf0elxglJ9tmpamqZzA7tL0ptKBcqtqLl6J9RESAKdvkpm0noExKm2 QkseD1Vw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCS9-0003kz-3c; Fri, 07 Dec 2018 09:29:45 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPk-0000zd-Tr for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:31 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id D594C20E1F; Fri, 7 Dec 2018 10:26:52 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id DCE2B20701; Fri, 7 Dec 2018 10:26:40 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 15/34] mtd: spi-nor: Expose some functions to manufacturer drivers Date: Fri, 7 Dec 2018 10:26:18 +0100 Message-Id: <20181207092637.18687-16-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012717_571009_78EC8CC9 X-CRM114-Status: GOOD ( 11.50 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Some manufacturers rely on the generic quad_enable()/set_4byte() implementations. Remove the static specifier and expose their prototypes in internals.h. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/core.c | 24 +++++++++--------------- drivers/mtd/spi-nor/internals.h | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index f3c8e4ac1158..0bdbedb464c1 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -113,7 +113,7 @@ static int write_sr(struct spi_nor *nor, u8 val) * Set write enable latch with Write Enable command. * Returns negative if error occurred. */ -static int write_enable(struct spi_nor *nor) +int write_enable(struct spi_nor *nor) { return nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0); } @@ -121,17 +121,11 @@ static int write_enable(struct spi_nor *nor) /* * Send write disable instruction to the chip. */ -static int write_disable(struct spi_nor *nor) +int write_disable(struct spi_nor *nor) { return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0); } -static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) -{ - return mtd->priv; -} - - static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size) { size_t i; @@ -322,7 +316,7 @@ static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor, return -ETIMEDOUT; } -static int spi_nor_wait_till_ready(struct spi_nor *nor) +int spi_nor_wait_till_ready(struct spi_nor *nor) { return spi_nor_wait_till_ready_with_timeout(nor, DEFAULT_READY_WAIT_JIFFIES); @@ -340,7 +334,7 @@ static int erase_chip(struct spi_nor *nor) return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); } -static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) +int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) { int ret = 0; @@ -357,7 +351,7 @@ static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) return ret; } -static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) +void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) { if (nor->unprepare) nor->unprepare(nor, ops); @@ -1140,7 +1134,7 @@ static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr) return 0; } -static int no_quad_enable(struct spi_nor *nor) +int no_quad_enable(struct spi_nor *nor) { return 0; } @@ -1155,7 +1149,7 @@ static int no_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int sr1_bit6_quad_enable(struct spi_nor *nor) +int sr1_bit6_quad_enable(struct spi_nor *nor) { int ret, val; @@ -3324,13 +3318,13 @@ void spi_nor_restore(struct spi_nor *nor) } EXPORT_SYMBOL_GPL(spi_nor_restore); -static int en4_ex4_set_4byte(struct spi_nor *nor, bool enable) +int en4_ex4_set_4byte(struct spi_nor *nor, bool enable) { return nor->write_reg(nor, enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B, NULL, 0); } -static int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable) +int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable) { int ret; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index c442d0bfa21a..5ed65f46333d 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -332,4 +332,20 @@ struct spi_nor_manufacturer { const struct spi_nor_fixups *fixups; }; +/* Core helpers. */ +int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); +int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable); +int sr1_bit6_quad_enable(struct spi_nor *nor); +int no_quad_enable(struct spi_nor *nor); +int write_enable(struct spi_nor *nor); +int write_disable(struct spi_nor *nor); +int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops); +void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops); +int spi_nor_wait_till_ready(struct spi_nor *nor); + +static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) +{ + return mtd->priv; +} + #endif /* __LINUX_MTD_SPI_NOR_INTERNALS_H */ From patchwork Fri Dec 7 09:26:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009296 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="D4ia5jPi"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6ty5725z9s3q for ; Fri, 7 Dec 2018 20:42:02 +1100 (AEDT) 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=LSWAQa/6h5/JVuLN/TGEre+HyK5T3o+78mcxAHSj4fE=; b=D4ia5jPikqkN28Jv1st+I7UTgO wP6u6N/zyE3lOqUJ6LlC+x2Df/bzMetuMLEp1wnfkG70u9JFHtfoeuyNlrNOxwjfFD5F7l08Z0D74 wBfuVCaD6QZOAEaQDj+3MJBNl0R38kfgz0Qv/hlO19LsrTzp6jXXgnbdUVMNjnkWd8PVtWOnIgpYL 17DeX8BecYClkAcGH8aMPPqWjUcx6/9vlQSPFxf/V/KYHX5M0/JowPgA1ElwYEISewIgy/CotBjZ9 DIv0IHjf3pPpKoOxN6Qx21JFstbNpq+kS9e5tB5hOSCQbQwCKtv1mhXYs3auS2zaqxpLfnyCkKyfn 6YgbMHpA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCds-0006PO-Or; Fri, 07 Dec 2018 09:41:52 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPv-0001KW-Au for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:46 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id DF01D20717; Fri, 7 Dec 2018 10:26:52 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 1C55220CFB; Fri, 7 Dec 2018 10:26:41 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 16/34] mtd: spi-nor: Move Atmel bits out of core.c Date: Fri, 7 Dec 2018 10:26:19 +0100 Message-Id: <20181207092637.18687-17-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012728_556112_A75AA3C7 X-CRM114-Status: GOOD ( 15.99 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Atmel chips, and move the Atmel definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/atmel.c | 47 +++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/core.c | 29 +++----------------- drivers/mtd/spi-nor/internals.h | 3 +++ 4 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 drivers/mtd/spi-nor/atmel.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 0d6c4967a445..fd8454d38b17 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 spi-nor-objs := core.o +spi-nor-objs += atmel.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c new file mode 100644 index 000000000000..a700a17fdead --- /dev/null +++ b/drivers/mtd/spi-nor/atmel.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info atmel_parts[] = { + /* Atmel -- some are (confusingly) marketed as "DataFlash" */ + { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, + { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, + + { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, + { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, + { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, + { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, + + { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, + { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, + { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, + { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, + + { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, +}; + +static int atmel_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; + + return 0; +} + +static const struct spi_nor_fixups atmel_fixups = { + .post_sfdp = atmel_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_atmel = { + .name = "atmel", + .parts = atmel_parts, + .nparts = ARRAY_SIZE(atmel_parts), + .fixups = &atmel_fixups, +}; diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 0bdbedb464c1..28b0d46aa3a0 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1401,22 +1401,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Atmel -- some are (confusingly) marketed as "DataFlash" */ - { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, - { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, - - { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, - { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, - { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, - { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, - - { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, - { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, - { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, - { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, - - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, - /* EON -- en25xxx */ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, @@ -1714,7 +1698,9 @@ static const struct flash_info spi_nor_ids[] = { { }, }; -static const struct spi_nor_manufacturer *manufacturers[0]; +static const struct spi_nor_manufacturer *manufacturers[] = { + &spi_nor_atmel, +}; static const struct flash_info * spi_nor_search_part_by_id(const struct flash_info *parts, unsigned int nparts, @@ -3394,11 +3380,6 @@ static void intel_post_sfdp_fixups(struct spi_nor *nor) nor->flags |= SNOR_F_CLR_SW_PROT_BITS; } -static void atmel_post_sfdp_fixups(struct spi_nor *nor) -{ - nor->flags |= SNOR_F_CLR_SW_PROT_BITS; -} - static void sst_post_sfdp_fixups(struct spi_nor *nor) { nor->flags |= SNOR_F_CLR_SW_PROT_BITS; @@ -3461,10 +3442,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, return nor->manufacturer->fixups->post_sfdp(nor, params); switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_ATMEL: - atmel_post_sfdp_fixups(nor); - break; - case SNOR_MFR_INTEL: intel_post_sfdp_fixups(nor); break; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 5ed65f46333d..9ad903a51846 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -332,6 +332,9 @@ struct spi_nor_manufacturer { const struct spi_nor_fixups *fixups; }; +/* Manufacturer drivers. */ +extern const struct spi_nor_manufacturer spi_nor_atmel; + /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009286 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="MIR6LbEp"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6hw1JP9z9s8J for ; Fri, 7 Dec 2018 20:33:20 +1100 (AEDT) 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=Yf3wFhMw45cbfcgyDAwEYXot+BTYHGqG8CiXzIG70jY=; b=MIR6LbEppOQW/D/huPw280pdb1 vYXP0d1ur12xQ3Zub1xFQwcOgHkuK0l62ETtp5/355D0T8m2o5ZNWD3u+ktBybarey0nO6YnyPUj7 EjjevaKXFiQptndLKJHe3bCOkiXBNfEPD/zaAJdBlj2pH6rvjjX3OQom/hCLDXblP9nQfkjxAMDCa VW9JLwIJ14UvYmjJsjVuRF4IWj3zaY7Qd7U70Hhfy8gasESqdWATPsSqA40AkJLPol0iSfPxexF3+ oHLkBpeWUa2WB2p/aCLcyR/Q70N2R9A55GSBpVzD7RwCmjbm0gtQ8TkbK616IrFsnGR2Dct9xsG8I WllLmK2Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCVU-0008Lw-U1; Fri, 07 Dec 2018 09:33:12 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPv-0001Ko-Ax for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:41 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 1956420E36; Fri, 7 Dec 2018 10:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 5321620D17; Fri, 7 Dec 2018 10:26:41 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 17/34] mtd: spi-nor: Move Eon bits out of core.c Date: Fri, 7 Dec 2018 10:26:20 +0100 Message-Id: <20181207092637.18687-18-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012728_069275_9B22CDE8 X-CRM114-Status: GOOD ( 16.32 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Eon chips, and move the Eon definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 12 +----------- drivers/mtd/spi-nor/eon.c | 28 ++++++++++++++++++++++++++++ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 drivers/mtd/spi-nor/eon.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index fd8454d38b17..496226314700 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 spi-nor-objs := core.o spi-nor-objs += atmel.o +spi-nor-objs += eon.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 28b0d46aa3a0..773f11f3f305 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1401,17 +1401,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, - { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, - /* ESMT */ { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, { "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, @@ -1700,6 +1689,7 @@ static const struct flash_info spi_nor_ids[] = { static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_atmel, + &spi_nor_eon, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/eon.c b/drivers/mtd/spi-nor/eon.c new file mode 100644 index 000000000000..ede195e08b5b --- /dev/null +++ b/drivers/mtd/spi-nor/eon.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info eon_parts[] = { + { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, + { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, + { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, + { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, + { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, + { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, + { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, + { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, + { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, +}; + +const struct spi_nor_manufacturer spi_nor_eon = { + .name = "eon", + .parts = eon_parts, + .nparts = ARRAY_SIZE(eon_parts), +}; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 9ad903a51846..a49b34268e88 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -334,6 +334,7 @@ struct spi_nor_manufacturer { /* Manufacturer drivers. */ extern const struct spi_nor_manufacturer spi_nor_atmel; +extern const struct spi_nor_manufacturer spi_nor_eon; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009270 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="iecWZRa5"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6d860qYz9s55 for ; Fri, 7 Dec 2018 20:30:04 +1100 (AEDT) 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=cx0wza+BcFIyShuWrTIx7qXlxsetyqN+RHr3ygXHJIQ=; b=iecWZRa518pFDxpQ1xjrmjYmUs yxUy45KXlRYzLcw/SFlF62hrmz4v1OA+GXmiJxZ+GKlAy4x0zF8ZWiTOTwRsykxR1zhMVytAg3B3B vNBYUGafsSJtBYJhQuxn7wuQCqSA6retmju6ZX8XgST2rsLZEws6Wg5Hcy86Q+6zN4S2XLMu4UfBi lKnyGdnaAieWMrQPu9+GrkTDAI+rBVxZ+G3YqpnK5pGw7p2m8T7CHSYQCxJiNvH6wRsl7imwtOfVp 2TypmxFy9UQO+XaVIJzwB5moHYSn7iV0Iq3dmHHqA5nzwI6gZuyR8vc6YdVk6X5vOicU0z/aH0qI0 oUSRkTrg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCSL-0003xy-U1; Fri, 07 Dec 2018 09:29:57 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPl-000102-4z for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:31 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 1AD1320701; Fri, 7 Dec 2018 10:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 8B5F620D23; Fri, 7 Dec 2018 10:26:41 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 18/34] mtd: spi-nor: Move ESMT bits out of core.c Date: Fri, 7 Dec 2018 10:26:21 +0100 Message-Id: <20181207092637.18687-19-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012718_125202_C3234E6F X-CRM114-Status: GOOD ( 15.64 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for ESMT chips, and move the ESMT definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 6 +----- drivers/mtd/spi-nor/esmt.c | 31 +++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 drivers/mtd/spi-nor/esmt.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 496226314700..cf9dd268efd3 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -2,6 +2,7 @@ spi-nor-objs := core.o spi-nor-objs += atmel.o spi-nor-objs += eon.o +spi-nor-objs += esmt.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 773f11f3f305..6d11f2cec49b 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1401,11 +1401,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* ESMT */ - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, - { "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, - { "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_LOCK) }, - /* Everspin */ { "mr25h128", CAT25_INFO( 16 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, @@ -1690,6 +1685,7 @@ static const struct flash_info spi_nor_ids[] = { static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_atmel, &spi_nor_eon, + &spi_nor_esmt, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/esmt.c b/drivers/mtd/spi-nor/esmt.c new file mode 100644 index 000000000000..9422939e798a --- /dev/null +++ b/drivers/mtd/spi-nor/esmt.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info esmt_parts[] = { + { + "f25l32pa", + INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) + }, + { + "f25l32qa", + INFO(0x8c4116, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) + }, + { + "f25l64qa", + INFO(0x8c4117, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_LOCK) + }, +}; + +const struct spi_nor_manufacturer spi_nor_esmt = { + .name = "esmt", + .parts = esmt_parts, + .nparts = ARRAY_SIZE(esmt_parts), +}; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index a49b34268e88..4dafa2b19c86 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -335,6 +335,7 @@ struct spi_nor_manufacturer { /* Manufacturer drivers. */ extern const struct spi_nor_manufacturer spi_nor_atmel; extern const struct spi_nor_manufacturer spi_nor_eon; +extern const struct spi_nor_manufacturer spi_nor_esmt; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009276 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="q0Y0gKmW"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6fW6bRYz9s3q for ; Fri, 7 Dec 2018 20:31:15 +1100 (AEDT) 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=ox+bAExJgdnPwxmkP96jwYA0+e6VPbwiXBxcfmIiTPU=; b=q0Y0gKmWO8IeFHD6iWPr7VrfqI GK1jFCdBWWNQ5u3ZL3XLKcXK3ntpgD4YWugLOYf+E99xB+XakVaq/vbJWK9aSQg06liomPOMhcHDU xiwxIVECheFSrxZ0Il5AfbCJm7px/Y0piEdQi/lR4/BYJaoJXLINcMVzUDI3Au5guoEB+hKeNx3xh dqUYUW0G+8BlWmD842VFrLBEaNsZiXPrLGd3c8NXM7t+hp2v0kaFYqoaPNPDabeX7ckAc4zyqDLM4 0uMAXVCghDDCp7Y+CzXygcxYEB5rASaorpEK/SIDVM7fWLhG/A9De9f0XOlGLwntMRIPlKzyIZhNu CYYA0R6g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCTX-0006K3-VP; Fri, 07 Dec 2018 09:31:11 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPq-00010C-0B for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:34 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 4CF6E20D17; Fri, 7 Dec 2018 10:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id C38E820E1D; Fri, 7 Dec 2018 10:26:41 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 19/34] mtd: spi-nor: Move Everspin bits out of core.c Date: Fri, 7 Dec 2018 10:26:22 +0100 Message-Id: <20181207092637.18687-20-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012723_269765_13F98C09 X-CRM114-Status: GOOD ( 14.92 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Everspin chips, and move the Everspin definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 7 +----- drivers/mtd/spi-nor/everspin.c | 39 +++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 drivers/mtd/spi-nor/everspin.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index cf9dd268efd3..9a9f499a299d 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -3,6 +3,7 @@ spi-nor-objs := core.o spi-nor-objs += atmel.o spi-nor-objs += eon.o spi-nor-objs += esmt.o +spi-nor-objs += everspin.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 6d11f2cec49b..3de5c6b4a49f 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1401,12 +1401,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Everspin */ - { "mr25h128", CAT25_INFO( 16 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - /* Fujitsu */ { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, @@ -1686,6 +1680,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_atmel, &spi_nor_eon, &spi_nor_esmt, + &spi_nor_everspin, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/everspin.c b/drivers/mtd/spi-nor/everspin.c new file mode 100644 index 000000000000..d04b7215df25 --- /dev/null +++ b/drivers/mtd/spi-nor/everspin.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info everspin_parts[] = { + { + "mr25h128", + CAT25_INFO(16 * 1024, 1, 256, 2, + SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "mr25h256", + CAT25_INFO(32 * 1024, 1, 256, 2, + SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "mr25h10", + CAT25_INFO(128 * 1024, 1, 256, 3, + SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "mr25h40", + CAT25_INFO(512 * 1024, 1, 256, 3, + SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, +}; + +const struct spi_nor_manufacturer spi_nor_everspin = { + .name = "everspin", + .parts = everspin_parts, + .nparts = ARRAY_SIZE(everspin_parts), +}; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 4dafa2b19c86..8b6adcfed798 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -336,6 +336,7 @@ struct spi_nor_manufacturer { extern const struct spi_nor_manufacturer spi_nor_atmel; extern const struct spi_nor_manufacturer spi_nor_eon; extern const struct spi_nor_manufacturer spi_nor_esmt; +extern const struct spi_nor_manufacturer spi_nor_everspin; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009274 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="PG6hJ3kJ"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6f366wSz9s3q for ; Fri, 7 Dec 2018 20:30:51 +1100 (AEDT) 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=L0EXpqyZvsoG1t62Yo9Xd+jhOTzzwXnMHqON+My8gcM=; b=PG6hJ3kJBMCI2gZLdxFbZUlaB7 1yi8GVvHyo9iAHxhLMjxHtccWtBJl6qlrrxhKD5yhCo4aChIucExtc0dt+/0apDeYAeHHlTW7T9p3 zJLEJnZHnPrvqdWEUpvZD+NhEnAnXqwkHpQz/YRcx6LLom5bgurtBKtVwpny/VPFCh4AxWypv9UC6 E5ZUNFDj4K1AEFefMV+6ofptPtU08Peq3A6p5x+taPyXBtxDm78P7UdxWzZ0aib6feWbQrfL1GE5U KUyUzb8vJueH2clBRWQitKQScSKJLb1cLd2BDP5zNRDpHAkhG+OxJHodF/9faLhrNdAM9cVVYKnPt BxhvLxtA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCT6-0005tr-Q8; Fri, 07 Dec 2018 09:30:44 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPq-000101-0V for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:34 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 771A720D23; Fri, 7 Dec 2018 10:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 061C720E20; Fri, 7 Dec 2018 10:26:42 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 20/34] mtd: spi-nor: Move Fujitsu bits out of spi-nor-core.c Date: Fri, 7 Dec 2018 10:26:23 +0100 Message-Id: <20181207092637.18687-21-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012723_137429_4FF7064C X-CRM114-Status: GOOD ( 14.88 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Fujitsu chips, and move the Fujitsu definitions outside of spi-nor-core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 4 +--- drivers/mtd/spi-nor/fujitsu.c | 20 ++++++++++++++++++++ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 drivers/mtd/spi-nor/fujitsu.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 9a9f499a299d..fc85f8602d11 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -4,6 +4,7 @@ spi-nor-objs += atmel.o spi-nor-objs += eon.o spi-nor-objs += esmt.o spi-nor-objs += everspin.o +spi-nor-objs += fujitsu.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 3de5c6b4a49f..4e83cd640128 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1401,9 +1401,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Fujitsu */ - { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, - /* GigaDevice */ { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, @@ -1681,6 +1678,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_eon, &spi_nor_esmt, &spi_nor_everspin, + &spi_nor_fujitsu, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/fujitsu.c b/drivers/mtd/spi-nor/fujitsu.c new file mode 100644 index 000000000000..5cd6aa7f5417 --- /dev/null +++ b/drivers/mtd/spi-nor/fujitsu.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info fujitsu_parts[] = { + { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, +}; + +const struct spi_nor_manufacturer spi_nor_fujitsu = { + .name = "fujitsu", + .parts = fujitsu_parts, + .nparts = ARRAY_SIZE(fujitsu_parts), +}; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 8b6adcfed798..5dffc0c51826 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -337,6 +337,7 @@ extern const struct spi_nor_manufacturer spi_nor_atmel; extern const struct spi_nor_manufacturer spi_nor_eon; extern const struct spi_nor_manufacturer spi_nor_esmt; extern const struct spi_nor_manufacturer spi_nor_everspin; +extern const struct spi_nor_manufacturer spi_nor_fujitsu; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009293 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="jR5k/QTm"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="M3Mabtoe"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6tb0Z82z9s3q for ; Fri, 7 Dec 2018 20:41:43 +1100 (AEDT) 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=/AIr5cqMtPfyOsX6FgOLzknzBxwHSD7fTaywPLd34cw=; b=jR5k/QTmkf5jhX8JNlOx8XMGmk iPxvqThux1hhFGzvqgtE3ddMBEMzomul/cRouklAPeQxUYlxJ9ErfDUsPzy1uYJ67e7sriDk8k/oZ L3dUuraLDtKTAgOHPgM/GBLGMynx2VxzDCKRp5NWyyPvQ2d1NM/0R3LdDg7JXRwK4qUdwRFvbcx7l 8nYoyrniJ7+Ml3naImL2JxWw4YVaUD48+RKQaEiKfGbNUfXHINqNjlvWykIeJ9xGyn8zaUI06tiPy V8uTwEtvhf8tannoQOpWQXft2coopbcKD7eXooPj4TbGSkwmR3FP46vhKLUQ+fyvg1k/DMhmzhmIi SwDK5qnw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCdW-00063n-Mg; Fri, 07 Dec 2018 09:41:30 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ7-0001n4-E0 for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=y4ZoWbj1ydAmF9m6wDiYQ/D1qMxwsX+OGHOjz5Y+GGQ=; b=M3MabtoeIICcNw7VqBqsJNZgY pIPshUFqXypAi6jGOmp7g13XhHw0D6LxNt9PswPq6BlxnxA3nUayX31TVCjKq2O8wGVqvu/qYOQt6 kKuwT7udw09mXDMQmekR1kjZn1lgBFnTsH4MZbi1DsAyqLhqznMmVqGZTvDFS/7wywwgKmFnwLYDO WodhBBTCrk9msINK7UFKGqYtX0nixdINvWXn67DeI+Y9/oFAN9i13r6fbAue9QtSSjvc686eK+kl/ Wn8jQDEiGMfbIyV8RDJ8BjmvATg8+31A8q8mzW7dc5w+z+dTZ1OGsO2BovH6IvWAvIYAJhA3ejkFq 0NyLvQTNw==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ3-0005hI-EZ for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:37 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id B647E20CFB; Fri, 7 Dec 2018 10:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 3E1EE20E21; Fri, 7 Dec 2018 10:26:42 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 21/34] mtd: spi-nor: Move GigaDevice bits out of core.c Date: Fri, 7 Dec 2018 10:26:24 +0100 Message-Id: <20181207092637.18687-22-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042735_722240_2B5D9831 X-CRM114-Status: GOOD ( 17.95 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for GigaDevice chips, and move the GigaDevice definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 51 +--------------------- drivers/mtd/spi-nor/gigadevice.c | 74 ++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 drivers/mtd/spi-nor/gigadevice.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index fc85f8602d11..ab2378d8b497 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -5,6 +5,7 @@ spi-nor-objs += eon.o spi-nor-objs += esmt.o spi-nor-objs += everspin.o spi-nor-objs += fujitsu.o +spi-nor-objs += gigadevice.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 4e83cd640128..c452c8adcc46 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1352,18 +1352,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) return 0; } -static int gd25q256_post_sfdp_fixups(struct spi_nor *nor, - struct spi_nor_flash_parameter *params) -{ - params->quad_enable = sr1_bit6_quad_enable; - - return 0; -} - -static const struct spi_nor_fixups gd25q256_fixups = { - .post_sfdp = gd25q256_post_sfdp_fixups, -}; - static int mx25l25635_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, @@ -1401,44 +1389,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* GigaDevice */ - { - "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "gd25lq32", INFO(0xc86016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - .fixups = &gd25q256_fixups, - }, - /* Intel/Numonyx -- xxxs33b */ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, @@ -1679,6 +1629,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_esmt, &spi_nor_everspin, &spi_nor_fujitsu, + &spi_nor_gigadevice, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c new file mode 100644 index 000000000000..34c64b6fd549 --- /dev/null +++ b/drivers/mtd/spi-nor/gigadevice.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static int gd25q256_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + params->quad_enable = sr1_bit6_quad_enable; + + return 0; +} + +static const struct spi_nor_fixups gd25q256_fixups = { + .post_sfdp = gd25q256_post_sfdp_fixups, +}; + +static const struct flash_info gigadevice_parts[] = { + { + "gd25q16", + INFO(0xc84015, 0, 64 * 1024, 32, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "gd25q32", + INFO(0xc84016, 0, 64 * 1024, 64, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "gd25lq32", + INFO(0xc86016, 0, 64 * 1024, 64, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "gd25q64", + INFO(0xc84017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "gd25lq64c", + INFO(0xc86017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "gd25q128", + INFO(0xc84018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "gd25q256", + INFO(0xc84019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + .fixups = &gd25q256_fixups, + }, +}; + +const struct spi_nor_manufacturer spi_nor_gigadevice = { + .name = "gigadevice", + .parts = gigadevice_parts, + .nparts = ARRAY_SIZE(gigadevice_parts), +}; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 5dffc0c51826..a21822513c26 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -338,6 +338,7 @@ extern const struct spi_nor_manufacturer spi_nor_eon; extern const struct spi_nor_manufacturer spi_nor_esmt; extern const struct spi_nor_manufacturer spi_nor_everspin; extern const struct spi_nor_manufacturer spi_nor_fujitsu; +extern const struct spi_nor_manufacturer spi_nor_gigadevice; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009283 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="a7GBeXjR"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="W2OTToN6"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6gv4DGYz9s3q for ; Fri, 7 Dec 2018 20:32:27 +1100 (AEDT) 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=pTvT4OWvo0HxPgDprpgBCWvkHW/YLptg+0BWzW3P8D4=; b=a7GBeXjRrcewZcFHiEJQpnUXQq /TdvULlUC6A6/B1BMtd2xNWTg97wJV95mjCt5L+UOEXBkwvZOZQ5UQgKMQusPWbkbtHFDoaSyQZAr o5oWlI86UhGcRt+ZpsM7IiH3Tl+MqBaS7a6gWefXbyIVs/4VfEgNuBj9B/UUqVfrGTF+0XpLhpuzc zEtfc69N8nkgJdOphh5VasMiRWgVJqIILF230ks25wyxeXDiOCOINvljcKNimu+xnvQ2LXYbswmqN 2vPpqKXbIiSDWuqjeIp2aDtSo3yRXMrqxzPI8gvdRKKV2wtkabXzp4HLk6kB5vPQr12XXXPQapC5b YQQOzN3Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCUg-0007XF-Kx; Fri, 07 Dec 2018 09:32:22 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ7-0001my-Ad for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=RFqbIPcUg3L0sPR5r5Vlqjtu7zipnEgw9rw2nbISW5c=; b=W2OTToN6sWnz1FVGv5n8NiDwQ 7o+F/Y/AMdhc1XZ0a3Xe/blg6gJgS4leask955aXpBWPdinNeA5+NfgQa6oJ7Fme3TXHbJ8FWWhTW N4CS6gruI+Dp/7GMd2yRhmaBk31CvEUP1ZNHNuybVYFhAfomLn/qoIp4JlSZ38uYMlCZptciD9WNr zi6abFAkYkPBLvQoHyBHMKHJCuyiiLV1w2duuVm+6LwNJanEK09l+FupXG9a5UUr/u02VQQmM0ytr fwMYyMqsElnV5UV/bNez6jQE2bui1eWtmnWsjULcLQJ2E6xyaw4vlRl3FdqU8sCyqy/rrS8khYH7T j5y7bENsg==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ2-0005hH-Nb for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:37 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id E0A9520E1D; Fri, 7 Dec 2018 10:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 70A0420E22; Fri, 7 Dec 2018 10:26:42 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 22/34] mtd: spi-nor: Move Intel bits out of core.c Date: Fri, 7 Dec 2018 10:26:25 +0100 Message-Id: <20181207092637.18687-23-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042735_065063_6566F0A3 X-CRM114-Status: GOOD ( 17.18 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Intel chips, and move the Intel definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 15 +------------- drivers/mtd/spi-nor/intel.c | 35 +++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 drivers/mtd/spi-nor/intel.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index ab2378d8b497..3d884b45a174 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -6,6 +6,7 @@ spi-nor-objs += esmt.o spi-nor-objs += everspin.o spi-nor-objs += fujitsu.o spi-nor-objs += gigadevice.o +spi-nor-objs += intel.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index c452c8adcc46..7788d7429318 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1389,11 +1389,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Intel/Numonyx -- xxxs33b */ - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, - { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, - /* ISSI */ { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, { "is25lq040b", INFO(0x9d4013, 0, 64 * 1024, 8, @@ -1630,6 +1625,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_everspin, &spi_nor_fujitsu, &spi_nor_gigadevice, + &spi_nor_intel, }; static const struct flash_info * @@ -3305,11 +3301,6 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor) } } -static void intel_post_sfdp_fixups(struct spi_nor *nor) -{ - nor->flags |= SNOR_F_CLR_SW_PROT_BITS; -} - static void sst_post_sfdp_fixups(struct spi_nor *nor) { nor->flags |= SNOR_F_CLR_SW_PROT_BITS; @@ -3372,10 +3363,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, return nor->manufacturer->fixups->post_sfdp(nor, params); switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_INTEL: - intel_post_sfdp_fixups(nor); - break; - case SNOR_MFR_ST: case SNOR_MFR_MICRON: st_micron_post_sfdp_fixups(nor); diff --git a/drivers/mtd/spi-nor/intel.c b/drivers/mtd/spi-nor/intel.c new file mode 100644 index 000000000000..99d49bc045c1 --- /dev/null +++ b/drivers/mtd/spi-nor/intel.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info intel_parts[] = { + { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, + { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, + { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, +}; + +static int intel_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; + + return 0; +} + +static const struct spi_nor_fixups intel_fixups = { + .post_sfdp = intel_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_intel = { + .name = "intel", + .parts = intel_parts, + .nparts = ARRAY_SIZE(intel_parts), + .fixups = &intel_fixups, +}; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index a21822513c26..f66bee137899 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -339,6 +339,7 @@ extern const struct spi_nor_manufacturer spi_nor_esmt; extern const struct spi_nor_manufacturer spi_nor_everspin; extern const struct spi_nor_manufacturer spi_nor_fujitsu; extern const struct spi_nor_manufacturer spi_nor_gigadevice; +extern const struct spi_nor_manufacturer spi_nor_intel; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); From patchwork Fri Dec 7 09:26:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009275 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="I6TUkWCV"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6fK1cvsz9s3q for ; Fri, 7 Dec 2018 20:31:05 +1100 (AEDT) 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=3rb+T2UAWz86LroxHYMKKbJEdxAwYnYAL39D/h6p+0M=; b=I6TUkWCV2A3MvJnwZU78NoszTK FHQup9jp1sM2HH9g/D6+gyEzvD2IYD1dcveHjvL/bTjnUPOXUnQh3YzedRikRgNM48A1VxqBNaGtz DeK16KGx6G3F/jQ8ypPqjykmgDscVR0fSJi/lBZEoBwZr5DTUymElL9d2G8ABjpPJQCtjfx0vdgiH 0a7OuOZVwX1YBf2Hj+GLYi6AceLlSxtTFLVhzwBa5av3608pt9BNC6gJYp1VrcN3bnSPxepZfRQyI S54cOv0YTh3LRQKpBSHmDD0WWGEky0y+wV3VuAlMyVTIXUiEngroYgmulcm6371XFqSjcLMe9L1lp c4DwfmOg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCTK-00067C-5H; Fri, 07 Dec 2018 09:30:58 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPq-000109-1U for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:34 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 23EC620E20; Fri, 7 Dec 2018 10:26:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id A463420E23; Fri, 7 Dec 2018 10:26:42 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 23/34] mtd: spi-nor: Move ISSI bits out of core.c Date: Fri, 7 Dec 2018 10:26:26 +0100 Message-Id: <20181207092637.18687-24-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012723_234216_3B37AF30 X-CRM114-Status: GOOD ( 15.51 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for ISSI chips, and move the ISSI definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 27 +------------ drivers/mtd/spi-nor/internals.h | 1 + drivers/mtd/spi-nor/issi.c | 67 +++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 26 deletions(-) create mode 100644 drivers/mtd/spi-nor/issi.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 3d884b45a174..51399122b497 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -7,6 +7,7 @@ spi-nor-objs += everspin.o spi-nor-objs += fujitsu.o spi-nor-objs += gigadevice.o spi-nor-objs += intel.o +spi-nor-objs += issi.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 7788d7429318..c1492f4c4f27 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1389,27 +1389,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* ISSI */ - { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, - { "is25lq040b", INFO(0x9d4013, 0, 64 * 1024, 8, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "is25lp080d", INFO(0x9d6014, 0, 64 * 1024, 16, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "is25lp032", INFO(0x9d6016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "is25lp064", INFO(0x9d6017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "is25lp128", INFO(0x9d6018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "is25lp256", INFO(0x9d6019, 0, 64 * 1024, 512, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "is25wp032", INFO(0x9d7016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "is25wp064", INFO(0x9d7017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - /* Macronix */ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, @@ -1459,11 +1438,6 @@ static const struct flash_info spi_nor_ids[] = { SECT_4K | USE_FSR | SPI_NOR_4B_OPCODES) }, - /* PMC */ - { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, - { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, - { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, - /* Spansion/Cypress -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ @@ -1626,6 +1600,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_fujitsu, &spi_nor_gigadevice, &spi_nor_intel, + &spi_nor_issi, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index f66bee137899..7e976e12be6c 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -340,6 +340,7 @@ extern const struct spi_nor_manufacturer spi_nor_everspin; extern const struct spi_nor_manufacturer spi_nor_fujitsu; extern const struct spi_nor_manufacturer spi_nor_gigadevice; extern const struct spi_nor_manufacturer spi_nor_intel; +extern const struct spi_nor_manufacturer spi_nor_issi; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c new file mode 100644 index 000000000000..cdcf4eec7247 --- /dev/null +++ b/drivers/mtd/spi-nor/issi.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info issi_parts[] = { + /* ISSI */ + { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, + { + "is25lq040b", + INFO(0x9d4013, 0, 64 * 1024, 8, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "is25lp080d", + INFO(0x9d6014, 0, 64 * 1024, 16, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "is25lp032", + INFO(0x9d6016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ) + }, + { + "is25lp064", + INFO(0x9d6017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ) + }, + { + "is25lp128", + INFO(0x9d6018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ) + }, + { + "is25lp256", + INFO(0x9d6019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ) + }, + { + "is25wp032", + INFO(0x9d7016, 0, 64 * 1024, 64, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "is25wp064", + INFO(0x9d7017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "is25wp128", + INFO(0x9d7018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + + /* PMC */ + { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, + { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, + { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, +}; + +const struct spi_nor_manufacturer spi_nor_issi = { + .name = "issi", + .parts = issi_parts, + .nparts = ARRAY_SIZE(issi_parts), +}; From patchwork Fri Dec 7 09:26:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009278 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="iIzET3c3"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="sPHu6ZSZ"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6g26BVsz9s3q for ; Fri, 7 Dec 2018 20:31:42 +1100 (AEDT) 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=jnfbQeiZ/IW8piAHmyW7HgEYNFfRCCEurn/2CdwYo5w=; b=iIzET3c3q566cKr+qYqhUGvh3F e1dYAQXcZkCeD47HO8aEwlL8VSPQX7q9CwqfUE0YPStn/oVelzVwlgVJsirCJirjHbzIdqGLFwZox tiYUMjYK5RvVKphPTm8B+D7pgC7wqDucv+Mx3AVoT6LaRyGq6XBv+yQxrPQk/2kcqJMJkv1yoR9Rf dfHTggdbHMaBx89t2tnt505m5L5D9MZrIUm4JBGUkZmxkzP3DezUuZnhoeUSecsQEbywy/7qwBXci eMR49GOiFiZhvqcNpFi71NsoOOXCRwih4XZmbEUADMGKE23GdPWgqjBJhY9M4R80yGAcJWQXcN7PY h6mii3Vg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCTy-0006m4-TO; Fri, 07 Dec 2018 09:31:38 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ7-0001nI-Le for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=TTRN1qLDqEQ0LzF6wcOUxOO1yHZx1QP72UWY5iHT4gk=; b=sPHu6ZSZJLrZ2hG78TGME+Dtu BoKIOSsXpmZa/2ID4PtpPKor6RuY7X0hdD7PAhayOBA9TQlCWIMnexKq6yB2Bipaja18F1HBeNLWb aItrN7NP2gvCClWNoCGGumgjcsJFZePa80XnjgN27sqA+4YRIm5Ufd+o2tMO5DTNJodkoZ/tw7Xeh P4UiUplRj3TDxVf9KRxehL6vCeA/RemzodQhOIMuM+JWcch4HEgY/LlU7PjOqH3sN+TCG5xRe89Ip 4ZNt5XuJ1Yo06hjrIZGIHWAo7/QxIDNXpNun87aGRy6eLlwyHXvHuVrPUmHUcMJVrCNzt9WlzmzLw zFjNsTa0w==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ2-0005hJ-M7 for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:37 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 6D1AD20E21; Fri, 7 Dec 2018 10:26:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id DC3B720D27; Fri, 7 Dec 2018 10:26:42 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 24/34] mtd: spi-nor: Move Macronix bits out of core.c Date: Fri, 7 Dec 2018 10:26:27 +0100 Message-Id: <20181207092637.18687-25-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042735_068437_9F423759 X-CRM114-Status: GOOD ( 21.40 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Macronix chips, and move the Macronix definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 63 +------------------ drivers/mtd/spi-nor/internals.h | 1 + drivers/mtd/spi-nor/macronix.c | 105 ++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 62 deletions(-) create mode 100644 drivers/mtd/spi-nor/macronix.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 51399122b497..c8ba7009e3ac 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -8,6 +8,7 @@ spi-nor-objs += fujitsu.o spi-nor-objs += gigadevice.o spi-nor-objs += intel.o spi-nor-objs += issi.o +spi-nor-objs += macronix.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index c1492f4c4f27..0118fafd7c65 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1352,31 +1352,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) return 0; } -static int -mx25l25635_post_bfpt_fixups(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) -{ - /* - * MX25L25635F supports 4B opcodes but MX25L25635E does not. - * Unfortunately, Macronix has re-used the same JEDEC ID for both - * variants which prevents us from defining a new entry in the parts - * table. - * We need a way to differentiate MX25L25635E and MX25L25635F, and it - * seems that the F version advertises support for Fast Read 4-4-4 in - * its BFPT table. - */ - if (bfpt->dwords[BFPT_DWORD(5)] & BFPT_DWORD5_FAST_READ_4_4_4) - nor->flags |= SNOR_F_4B_OPCODES; - - return 0; -} - -static struct spi_nor_fixups mx25l25635_fixups = { - .post_bfpt = mx25l25635_post_bfpt_fixups, -}; - /* NOTE: double check command sets and memory organization when you add * more nor chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. @@ -1389,33 +1364,6 @@ static struct spi_nor_fixups mx25l25635_fixups = { * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Macronix */ - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, - { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) }, - { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) }, - { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, - { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, - SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - .fixups = &mx25l25635_fixups }, - { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) }, - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, - { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, - { "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, - { "mx66l1g45g", INFO(0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, - /* Micron <--> ST Micro */ { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, @@ -1601,6 +1549,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_gigadevice, &spi_nor_intel, &spi_nor_issi, + &spi_nor_macronix, }; static const struct flash_info * @@ -3252,12 +3201,6 @@ static void st_micron_post_sfdp_fixups(struct spi_nor *nor) nor->quad_enable = no_quad_enable; } -static void macronix_post_sfdp_fixups(struct spi_nor *nor) -{ - nor->set_4byte = en4_ex4_set_4byte; - nor->quad_enable = sr1_bit6_quad_enable; -} - static void winbond_post_sfdp_fixups(struct spi_nor *nor) { nor->set_4byte = winbond_set_4byte; @@ -3343,10 +3286,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, st_micron_post_sfdp_fixups(nor); break; - case SNOR_MFR_MACRONIX: - macronix_post_sfdp_fixups(nor); - break; - case SNOR_MFR_SPANSION: spansion_post_sfdp_fixups(nor); break; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 7e976e12be6c..cb8968824098 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -341,6 +341,7 @@ extern const struct spi_nor_manufacturer spi_nor_fujitsu; extern const struct spi_nor_manufacturer spi_nor_gigadevice; extern const struct spi_nor_manufacturer spi_nor_intel; extern const struct spi_nor_manufacturer spi_nor_issi; +extern const struct spi_nor_manufacturer spi_nor_macronix; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c new file mode 100644 index 000000000000..cddd9c302826 --- /dev/null +++ b/drivers/mtd/spi-nor/macronix.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static int +mx25l25635_post_bfpt_fixups(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) +{ + /* + * MX25L25635F supports 4B opcodes but MX25L25635E does not. + * Unfortunately, Macronix has re-used the same JEDEC ID for both the + * variants which prevents us from defining a new entry in the parts + * table. + * We need a way to differentiate MX25L25635E and MX25L25635F, and it + * seems that the F version advertises support for Fast Read 4-4-4 in + * its BFPT table. + */ + if (bfpt->dwords[BFPT_DWORD(5)] & BFPT_DWORD5_FAST_READ_4_4_4) + nor->flags |= SNOR_F_4B_OPCODES; + + return 0; +} + +static struct spi_nor_fixups mx25l25635_fixups = { + .post_bfpt = mx25l25635_post_bfpt_fixups, +}; + +static const struct flash_info macronix_parts[] = { + { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, + { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, + { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, + { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, + { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, + { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, + { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, + { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, + { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) }, + { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) }, + { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) }, + { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, + { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, + { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, + { + "mx25u12835f", + INFO(0xc22538, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "mx25l25635e", + INFO(0xc22019, 0, 64 * 1024, 512, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + .fixups = &mx25l25635_fixups, + }, + { + "mx25u25635f", + INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) + }, + { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, + { + "mx66l51235l", + INFO(0xc2201a, 0, 64 * 1024, 1024, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) + }, + { + "mx66u51235f", + INFO(0xc2253a, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_4B_OPCODES) + }, + { + "mx66l1g45g", + INFO(0xc2201b, 0, 64 * 1024, 2048, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, +}; + +static int macronix_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + nor->set_4byte = en4_ex4_set_4byte; + nor->quad_enable = sr1_bit6_quad_enable; + + return 0; +} + +static const struct spi_nor_fixups macronix_fixups = { + .post_sfdp = macronix_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_macronix = { + .name = "macronix", + .parts = macronix_parts, + .nparts = ARRAY_SIZE(macronix_parts), + .fixups = ¯onix_fixups, +}; From patchwork Fri Dec 7 09:26:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009300 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="kk68PZRW"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="nhXOfpoj"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6x70fLnz9s7T for ; Fri, 7 Dec 2018 20:43:55 +1100 (AEDT) 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=GX/j+tytgd2mkPUx1RGCcGly6cPKj/0eUl+TVsXlxBI=; b=kk68PZRWzGvfFbyPcni1RGDcVD I+m3LW7BKN5Kl7bgsWayHN1XWpX+C1AWzYhwqQQnyBJUawhwZrueeRif4GIzNenf/F/ImSeIUtuqv bSds1Sf7/cr0HRYq7w52JSU3CCy9neg4BDokOTmilxlYSLjEaC4pH4WTcAY/pMOS8yJaMMS//lW65 Vv25wIiyXxCxoe/BkbdRZjcN0KEYrc8temwKcQ+N4a/CupfCzrUGo9j9SsAXkM0YeZU+o3yNgfmt6 rLQVN4ioaIIjUrsmiPUgWdF1Z+U4biJh9KruGCd8qn+j78mVLvlaE6+yEVpEZ3IIbHrPBc9tmNc2D XUThNYjw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCfl-0007vr-Ff; Fri, 07 Dec 2018 09:43:49 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCfH-0007MB-Lw for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:43:19 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=fll7EnZ83us84LoIiv9YEYpUw7z30rFyp6gQvAYtrjs=; b=nhXOfpojaiRtt68lB4yNz7WR+ V7XhGLLb3be3oDL/MlbCgwjesaKMgHET/yarvJFB2u9zNlredUNwfEm7WloTVtNSUoCTP5h8oplhq fZK/XIjB+nhbreFaEwqS0QrJPVTZAF5o7wAB/ds0fRUnizPREtfbzj3DFex06Y+gCehpyVT1gdsni mt47HMY4msB82BQ9EzL9euQVhd+OvhCjz0fDccyK4YHa4Sh95boK28Yeb5zm1jGHlWhRncuwXo3gK Y6/osGwzqfCkXM5I0LE9V/SGBEiAvsMJcnVn6Z4IL4L84SAECwThKvssAYh3+KjrGq969AFkVQ7Wd fcbUpy5lQ==; Received: from mail.bootlin.com ([62.4.15.54]) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ0-0001T5-Ah for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:34 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 0828A20CC3; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 1D7E320E25; Fri, 7 Dec 2018 10:26:43 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 25/34] mtd: spi-nor: Move Micron/ST bits out of core.c Date: Fri, 7 Dec 2018 10:26:28 +0100 Message-Id: <20181207092637.18687-26-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_092732_396392_B5BCDDE9 X-CRM114-Status: GOOD ( 22.89 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on casper.infradead.org summary: Content analysis details: (-0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Micron/ST chips, and move the Micron/ST definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 73 +------------------ drivers/mtd/spi-nor/internals.h | 2 + drivers/mtd/spi-nor/micron-st.c | 121 ++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 71 deletions(-) create mode 100644 drivers/mtd/spi-nor/micron-st.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index c8ba7009e3ac..3cbd445518e9 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -9,6 +9,7 @@ spi-nor-objs += gigadevice.o spi-nor-objs += intel.o spi-nor-objs += issi.o spi-nor-objs += macronix.o +spi-nor-objs += micron-st.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 0118fafd7c65..7282c261da88 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1364,28 +1364,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Micron <--> ST Micro */ - { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, - { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, - { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, - { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, - - /* Micron */ - { - "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512, - SECT_4K | USE_FSR | SPI_NOR_4B_OPCODES) - }, - /* Spansion/Cypress -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ @@ -1433,42 +1411,6 @@ static const struct flash_info spi_nor_ids[] = { { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, { "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - /* ST Microelectronics -- newer production may have feature updates */ - { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, - { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, - { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, - { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, - { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, - { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, - { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, - { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, - { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, - - { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, - { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, - { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, - { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, - { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, - { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, - { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, - { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, - { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, - - { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, - { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, - { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, - - { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, - { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, - { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, - - { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, - { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, - /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, @@ -1550,6 +1492,8 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_intel, &spi_nor_issi, &spi_nor_macronix, + &spi_nor_micron, + &spi_nor_st, }; static const struct flash_info * @@ -3193,14 +3137,6 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable) return ret; } -static void st_micron_post_sfdp_fixups(struct spi_nor *nor) -{ - /* All ST/Micron NORs support the unlock/lock operations. */ - nor->flags |= SNOR_F_HAS_LOCK; - nor->set_4byte = en4_ex4_wen_set_4byte; - nor->quad_enable = no_quad_enable; -} - static void winbond_post_sfdp_fixups(struct spi_nor *nor) { nor->set_4byte = winbond_set_4byte; @@ -3281,11 +3217,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, return nor->manufacturer->fixups->post_sfdp(nor, params); switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_ST: - case SNOR_MFR_MICRON: - st_micron_post_sfdp_fixups(nor); - break; - case SNOR_MFR_SPANSION: spansion_post_sfdp_fixups(nor); break; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index cb8968824098..888ef8d25f6b 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -342,6 +342,8 @@ extern const struct spi_nor_manufacturer spi_nor_gigadevice; extern const struct spi_nor_manufacturer spi_nor_intel; extern const struct spi_nor_manufacturer spi_nor_issi; extern const struct spi_nor_manufacturer spi_nor_macronix; +extern const struct spi_nor_manufacturer spi_nor_micron; +extern const struct spi_nor_manufacturer spi_nor_st; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c new file mode 100644 index 000000000000..7d9574d587a9 --- /dev/null +++ b/drivers/mtd/spi-nor/micron-st.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static int micron_st_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + /* All ST/Micron NORs support the unlock/lock operations. */ + nor->flags |= SNOR_F_HAS_LOCK; + nor->set_4byte = en4_ex4_wen_set_4byte; + nor->quad_enable = no_quad_enable; + + return 0; +} + +static const struct spi_nor_fixups micron_st_fixups = { + .post_sfdp = micron_st_post_sfdp_fixups, +}; + +static const struct flash_info micron_parts[] = { + { + "mt35xu512aba", + INFO(0x2c5b1a, 0, 128 * 1024, 512, + SECT_4K | USE_FSR | SPI_NOR_4B_OPCODES) + }, +}; + +const struct spi_nor_manufacturer spi_nor_micron = { + .name = "micron", + .parts = micron_parts, + .nparts = ARRAY_SIZE(micron_parts), + .fixups = µn_st_fixups, +}; + +static const struct flash_info st_parts[] = { + { + "n25q016a", + INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) + }, + { + "n25q032", + INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) + }, + { + "n25q032a", + INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) + }, + { + "n25q064", + INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) + }, + { + "n25q064a", + INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) + }, + { + "n25q128a11", + INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) + }, + { + "n25q128a13", + INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) + }, + { + "n25q256a", + INFO(0x20ba19, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "n25q256ax1", + INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) + }, + { + "n25q512a", + INFO(0x20bb20, 0, 64 * 1024, 1024, + SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) + }, + { + "n25q512ax3", + INFO(0x20ba20, 0, 64 * 1024, 1024, + SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) + }, + { + "n25q00", + INFO(0x20ba21, 0, 64 * 1024, 2048, + SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) + }, + { + "n25q00a", + INFO(0x20bb21, 0, 64 * 1024, 2048, + SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) + }, + { + "mt25qu02g", + INFO(0x20bb22, 0, 64 * 1024, 4096, + SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) + }, + { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, + { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, + { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, + { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, + { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, + { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, + { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, + { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, + { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, +}; + +const struct spi_nor_manufacturer spi_nor_st = { + .name = "st", + .parts = st_parts, + .nparts = ARRAY_SIZE(st_parts), + .fixups = µn_st_fixups, +}; From patchwork Fri Dec 7 09:26:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009277 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="izKljwey"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6fn3tspz9s3q for ; Fri, 7 Dec 2018 20:31:29 +1100 (AEDT) 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=7mYahtOwxOHJPIttJD0bRmtD53NxMCPCNaJj5QSyivk=; b=izKljweyuStzDAorbW7fFPwjbP fFiz6fl8UvTY56F3M0asBQP5CtmqnE7h5ShDBRgKG1U4FvSQq5t95mwa2clMuoom96AOT2IBhgLtG qwrvD6iGuzGoGbev5AO16nu5fPTR23T18cGzxaHco4gJ5/tdYGy+Kqqaqu0aIIpG5LMSO/ZlIp8XQ bHlzhYtB2o9cnSSyZoMEey8/FSuPPJ6goqBZOfJoxwEGLUvpnrmliageYyyCr3YVRLwPDE4RE9DVr LGzhCUpyDNoDldAawXRG/lOobzpTVD7Ps+ostZiOMCIadlgJsixLjSoQQzxL1XSHUhWr+TRjWNSzo dhbO1KFg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCTk-0006XQ-Jx; Fri, 07 Dec 2018 09:31:24 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPq-0000zf-1v for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:35 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 1156F20CDF; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 5146920E26; Fri, 7 Dec 2018 10:26:43 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 26/34] mtd: spi-nor: Move Spansion bits out of core.c Date: Fri, 7 Dec 2018 10:26:29 +0100 Message-Id: <20181207092637.18687-27-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012723_310214_F1248696 X-CRM114-Status: GOOD ( 18.03 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Spansion chips, and move the Spansion definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 50 +----------- drivers/mtd/spi-nor/internals.h | 1 + drivers/mtd/spi-nor/spansion.c | 137 ++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 49 deletions(-) create mode 100644 drivers/mtd/spi-nor/spansion.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 3cbd445518e9..81edb2734e90 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -10,6 +10,7 @@ spi-nor-objs += intel.o spi-nor-objs += issi.o spi-nor-objs += macronix.o spi-nor-objs += micron-st.o +spi-nor-objs += spansion.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 7282c261da88..a7f309ffe28c 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1364,38 +1364,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Spansion/Cypress -- single (large) sector size only, at least - * for the chips listed here (without boot sectors). - */ - { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) }, - { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, - { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, - { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, - { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, - { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, - { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, - { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, - { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, - { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, - { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, - { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, - { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, - { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, - { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, - { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, - { "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, - { "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, - { "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, - /* SST -- large erase sizes are "overlays", "sectors" are 4K */ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, @@ -1493,6 +1461,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_issi, &spi_nor_macronix, &spi_nor_micron, + &spi_nor_spansion, &spi_nor_st, }; @@ -3142,19 +3111,6 @@ static void winbond_post_sfdp_fixups(struct spi_nor *nor) nor->set_4byte = winbond_set_4byte; } -static void spansion_post_sfdp_fixups(struct spi_nor *nor) -{ - struct mtd_info *mtd = &nor->mtd; - - if (mtd->size > SZ_16M) { - nor->flags |= SNOR_F_4B_OPCODES; - - /* No small sector erase for 4-byte command set */ - nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; - } -} - static void sst_post_sfdp_fixups(struct spi_nor *nor) { nor->flags |= SNOR_F_CLR_SW_PROT_BITS; @@ -3217,10 +3173,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, return nor->manufacturer->fixups->post_sfdp(nor, params); switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_SPANSION: - spansion_post_sfdp_fixups(nor); - break; - case SNOR_MFR_SST: sst_post_sfdp_fixups(nor); break; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 888ef8d25f6b..b68c16194978 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -343,6 +343,7 @@ extern const struct spi_nor_manufacturer spi_nor_intel; extern const struct spi_nor_manufacturer spi_nor_issi; extern const struct spi_nor_manufacturer spi_nor_macronix; extern const struct spi_nor_manufacturer spi_nor_micron; +extern const struct spi_nor_manufacturer spi_nor_spansion; extern const struct spi_nor_manufacturer spi_nor_st; /* Core helpers. */ diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c new file mode 100644 index 000000000000..964f6e072d6c --- /dev/null +++ b/drivers/mtd/spi-nor/spansion.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include +#include + +#include "internals.h" + +static const struct flash_info spansion_parts[] = { + { + "s25sl032p", + INFO(0x010215, 0x4d00, 64 * 1024, 64, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "s25sl064p", + INFO(0x010216, 0x4d00, 64 * 1024, 128, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "s25fl256s0", + INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) + }, + { + "s25fl256s1", + INFO(0x010219, 0x4d01, 64 * 1024, 512, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) + }, + { + "s25fl512s", + INFO(0x010220, 0x4d00, 256 * 1024, 256, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) + }, + { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, + { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, + { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, + { + "s25fl128s", + INFO6(0x012018, 0x4d0180, 64 * 1024, 256, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) + }, + { + "s25fl129p0", + INFO(0x012018, 0x4d00, 256 * 1024, 64, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) + }, + { + "s25fl129p1", + INFO(0x012018, 0x4d01, 64 * 1024, 256, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) + }, + { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, + { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, + { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, + { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, + { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, + { + "s25fl004k", + INFO(0xef4013, 0, 64 * 1024, 8, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "s25fl008k", + INFO(0xef4014, 0, 64 * 1024, 16, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "s25fl016k", + INFO(0xef4015, 0, 64 * 1024, 32, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { + "s25fl116k", + INFO(0x014015, 0, 64 * 1024, 32, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, + { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, + { + "s25fl204k", + INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) + }, + { + "s25fl208k", + INFO(0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) + }, + { + "s25fl064l", + INFO(0x016017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_4B_OPCODES) + }, + { + "s25fl128l", + INFO(0x016018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_4B_OPCODES) + }, + { + "s25fl256l", + INFO(0x016019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_4B_OPCODES) + }, +}; + +static int spansion_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + struct mtd_info *mtd = &nor->mtd; + + if (mtd->size > SZ_16M) { + nor->flags |= SNOR_F_4B_OPCODES; + + /* No small sector erase for 4-byte command set */ + nor->erase_opcode = SPINOR_OP_SE; + nor->mtd.erasesize = nor->info->sector_size; + } + + return 0; +} + +static const struct spi_nor_fixups spansion_fixups = { + .post_sfdp = spansion_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_spansion = { + .name = "spansion", + .parts = spansion_parts, + .nparts = ARRAY_SIZE(spansion_parts), + .fixups = &spansion_fixups, +}; From patchwork Fri Dec 7 09:26:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009282 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="b9+svgrC"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="WbOWuQjh"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6gZ6y3kz9s3q for ; Fri, 7 Dec 2018 20:32:10 +1100 (AEDT) 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=MqfCpqpCniMfMmtme/XOcPRnll5wEENfPv3xklXH0q0=; b=b9+svgrCvajUy381BC+elNAKid w0+a8g53D1p/hUqwZGL6QqPTQ0eZsDzFR1dme9xce+Qq2vX9VnGwSNI0WW5CtzlCtPqQo2zDCdrro cWWgGCpgxzu7DpDIlSoZXre4N0UUFlJ+Y/LbctV14YhnlJBBl9LBsK6STJfzV1bt82rzm0AnznTft A16zE4CJSIOD+suTHFWtYttSiFYL6VboXQMyRjxnputXee5z8vdFTQE8dz9akRv/7zOnmY8SegBzb /KPIJywIjN4zFHLnyrE+TQyGa7ydIbHhORfM+jJiIPLX+AhjDoLm1CgjneAAXFjxHrd5IwPt1MK6p M/dhj1UQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCUP-0007GQ-VB; Fri, 07 Dec 2018 09:32:05 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ6-0001m2-H6 for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=jMmVlwkKXVaKmlqP95oX9fjPNe4+2h+hpTKSxRIX7mc=; b=WbOWuQjhxXSSe/VmsO3kP+JUG 8Ipe670hw7yFF7/6QVPj3K5ujtGU1nxm/ad8gUe8MG0EiZVa9ndf/+vXx63v81XJZ13RQi/B5EbjE 2R6SVQn33ghL3kcnf3p/C2x0VKId1S88BCXWAgvgYmn04fnukPqwmYg9CDdgMfAvcoYcVTXvWE9Vp 1J1C95eEC64geSK/C28wWtEUQ5slk9pB6ysR1Usp4bl7ldXfgkVp5niQJYkCRw1XxUFp/qzRw47Cm KhaTqpEn2Q7ArQpDWSoE7Bsy/Tc+GWSlSwW+xQ61QChTbImUaePDNVl3hfKJQfO3GoMq4jGIhYkFh JAkZ5h4Bw==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ2-0005hK-Lq for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:36 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 138E220711; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 831C920E27; Fri, 7 Dec 2018 10:26:43 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 27/34] mtd: spi-nor: Move SST bits out of core.c Date: Fri, 7 Dec 2018 10:26:30 +0100 Message-Id: <20181207092637.18687-28-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042735_001439_9A6F9CCC X-CRM114-Status: GOOD ( 25.31 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for SST chips, and move the SST definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 111 +-------------------------- drivers/mtd/spi-nor/internals.h | 1 + drivers/mtd/spi-nor/sst.c | 132 ++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 109 deletions(-) create mode 100644 drivers/mtd/spi-nor/sst.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 81edb2734e90..c41804252e27 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -11,6 +11,7 @@ spi-nor-objs += issi.o spi-nor-objs += macronix.o spi-nor-objs += micron-st.o spi-nor-objs += spansion.o +spi-nor-objs += sst.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index a7f309ffe28c..4721cf812dfe 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1364,21 +1364,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, - { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, - { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, - { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, - { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, - { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, - { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, - { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, - { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, - { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, - { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, - { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, - { "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, @@ -1462,6 +1447,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_macronix, &spi_nor_micron, &spi_nor_spansion, + &spi_nor_sst, &spi_nor_st, }; @@ -1551,85 +1537,6 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, return ret; } -static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) -{ - struct spi_nor *nor = mtd_to_spi_nor(mtd); - size_t actual; - int ret; - - dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); - - ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); - if (ret) - return ret; - - write_enable(nor); - - nor->sst_write_second = false; - - actual = to % 2; - /* Start write from odd address. */ - if (actual) { - nor->program_opcode = SPINOR_OP_BP; - - /* write one byte. */ - ret = nor->write(nor, to, 1, buf); - if (ret < 0) - goto sst_write_err; - WARN(ret != 1, "While writing 1 byte written %i bytes\n", - (int)ret); - ret = spi_nor_wait_till_ready(nor); - if (ret) - goto sst_write_err; - } - to += actual; - - /* Write out most of the data here. */ - for (; actual < len - 1; actual += 2) { - nor->program_opcode = SPINOR_OP_AAI_WP; - - /* write two bytes. */ - ret = nor->write(nor, to, 2, buf + actual); - if (ret < 0) - goto sst_write_err; - WARN(ret != 2, "While writing 2 bytes written %i bytes\n", - (int)ret); - ret = spi_nor_wait_till_ready(nor); - if (ret) - goto sst_write_err; - to += 2; - nor->sst_write_second = true; - } - nor->sst_write_second = false; - - write_disable(nor); - ret = spi_nor_wait_till_ready(nor); - if (ret) - goto sst_write_err; - - /* Write out trailing byte if it exists. */ - if (actual != len) { - write_enable(nor); - - nor->program_opcode = SPINOR_OP_BP; - ret = nor->write(nor, to, 1, buf + actual); - if (ret < 0) - goto sst_write_err; - WARN(ret != 1, "While writing 1 byte written %i bytes\n", - (int)ret); - ret = spi_nor_wait_till_ready(nor); - if (ret) - goto sst_write_err; - write_disable(nor); - actual += 1; - } -sst_write_err: - *retlen += actual; - spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); - return ret; -} - /* * Write an address range to the nor chip. Data must be written in * FLASH_PAGESIZE chunks. The address range may be any size provided @@ -3111,11 +3018,6 @@ static void winbond_post_sfdp_fixups(struct spi_nor *nor) nor->set_4byte = winbond_set_4byte; } -static void sst_post_sfdp_fixups(struct spi_nor *nor) -{ - nor->flags |= SNOR_F_CLR_SW_PROT_BITS; -} - static int s3an_post_sfdp_fixups(struct spi_nor *nor) { int ret; @@ -3173,10 +3075,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, return nor->manufacturer->fixups->post_sfdp(nor, params); switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_SST: - sst_post_sfdp_fixups(nor); - break; - case SNOR_MFR_WINBOND: winbond_post_sfdp_fixups(nor); break; @@ -3307,12 +3205,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, mtd->_erase = spi_nor_erase; mtd->_read = spi_nor_read; mtd->_resume = spi_nor_resume; - - /* sst nor chips use AAI word program */ - if (info->flags & SST_WRITE) - mtd->_write = sst_write; - else - mtd->_write = spi_nor_write; + mtd->_write = spi_nor_write; if (info->flags & USE_FSR) nor->flags |= SNOR_F_USE_FSR; diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index b68c16194978..298b4a855774 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -344,6 +344,7 @@ extern const struct spi_nor_manufacturer spi_nor_issi; extern const struct spi_nor_manufacturer spi_nor_macronix; extern const struct spi_nor_manufacturer spi_nor_micron; extern const struct spi_nor_manufacturer spi_nor_spansion; +extern const struct spi_nor_manufacturer spi_nor_sst; extern const struct spi_nor_manufacturer spi_nor_st; /* Core helpers. */ diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c new file mode 100644 index 000000000000..8d9a8fbfbcd9 --- /dev/null +++ b/drivers/mtd/spi-nor/sst.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info sst_parts[] = { + { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, + { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, + { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, + { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, + { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, + { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, + { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, + { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, + { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, + { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, + { + "sst26vf064b", + INFO(0xbf2643, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, +}; + +static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + size_t actual; + int ret; + + dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); + + ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); + if (ret) + return ret; + + write_enable(nor); + + nor->sst_write_second = false; + + actual = to % 2; + /* Start write from odd address. */ + if (actual) { + nor->program_opcode = SPINOR_OP_BP; + + /* write one byte. */ + ret = nor->write(nor, to, 1, buf); + if (ret < 0) + goto sst_write_err; + WARN(ret != 1, "While writing 1 byte written %i bytes\n", + (int)ret); + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto sst_write_err; + } + to += actual; + + /* Write out most of the data here. */ + for (; actual < len - 1; actual += 2) { + nor->program_opcode = SPINOR_OP_AAI_WP; + + /* write two bytes. */ + ret = nor->write(nor, to, 2, buf + actual); + if (ret < 0) + goto sst_write_err; + WARN(ret != 2, "While writing 2 bytes written %i bytes\n", + (int)ret); + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto sst_write_err; + to += 2; + nor->sst_write_second = true; + } + nor->sst_write_second = false; + + write_disable(nor); + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto sst_write_err; + + /* Write out trailing byte if it exists. */ + if (actual != len) { + write_enable(nor); + + nor->program_opcode = SPINOR_OP_BP; + ret = nor->write(nor, to, 1, buf + actual); + if (ret < 0) + goto sst_write_err; + WARN(ret != 1, "While writing 1 byte written %i bytes\n", + (int)ret); + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto sst_write_err; + write_disable(nor); + actual += 1; + } +sst_write_err: + *retlen += actual; + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); + return ret; +} + +static int sst_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + nor->flags |= SNOR_F_CLR_SW_PROT_BITS; + + /* sst nor chips use AAI word program */ + if (nor->info->flags & SST_WRITE) + nor->mtd._write = sst_write; + + return 0; +} + +static const struct spi_nor_fixups sst_fixups = { + .post_sfdp = sst_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_sst = { + .name = "sst", + .parts = sst_parts, + .nparts = ARRAY_SIZE(sst_parts), + .fixups = &sst_fixups, +}; From patchwork Fri Dec 7 09:26:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009280 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="VOZAtExa"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6gN1l6lz9s3q for ; Fri, 7 Dec 2018 20:32:00 +1100 (AEDT) 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=NiZd/vHY82m5dnkrqfi4zgusu/jLEVD+5uBWk7nkQPo=; b=VOZAtExaTzfPWAXAy4f54K27Gu tUoeGd7iE+ZB8qZgMUUM8F1vdg9jXmKxuoxQ1LP+hOG0rBS7bMlYbpFeLJXjcF2fuQU09okoNyKP3 ft2/SAk5a+Il/3Jbk5yIVa88aItwE6bLss+lpxWjIfbfdpVQqK5HqUNJiaqz27xL0Q+C5sOQH188H smJKFJemTKyrJEiSx8VKKUrfbfFZ3dHoFD4UGkQAXl29yyPCq7r9hY45ceDf6jjWgRy/fQXWmvZ2p y3w6Tt8K381h2VFUi7BteL3q6N4yF5Th38nPLLf9lgFISdNa6ZJT28cuxFtrCqSa8+uqmLTWeab8x kxRYhoxQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCUB-0006yz-Nl; Fri, 07 Dec 2018 09:31:51 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPq-00010A-5g for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:39 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 1520320D27; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id B5FA720E29; Fri, 7 Dec 2018 10:26:43 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 28/34] mtd: spi-nor: Move Winbond bits out of core.c Date: Fri, 7 Dec 2018 10:26:31 +0100 Message-Id: <20181207092637.18687-29-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012723_298760_7F5E19A1 X-CRM114-Status: GOOD ( 16.81 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Winbond chips, and move the Winbond definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 88 +----------------------- drivers/mtd/spi-nor/internals.h | 1 + drivers/mtd/spi-nor/winbond.c | 116 ++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 87 deletions(-) create mode 100644 drivers/mtd/spi-nor/winbond.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index c41804252e27..f74628184261 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -12,6 +12,7 @@ spi-nor-objs += macronix.o spi-nor-objs += micron-st.o spi-nor-objs += spansion.o spi-nor-objs += sst.o +spi-nor-objs += winbond.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 4721cf812dfe..ff6485473a90 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1364,57 +1364,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ - { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, - { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, - { - "w25q16dw", INFO(0xef6015, 0, 64 * 1024, 32, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, - { "w25q20cl", INFO(0xef4012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25q20bw", INFO(0xef5012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25q20ew", INFO(0xef6012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, - { - "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "w25q32jv", INFO(0xef7016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, - { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, - { - "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { - "w25q128jv", INFO(0xef7018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - }, - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024, - SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, - /* Catalyst / On Semiconductor -- non-JEDEC */ { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, @@ -1449,6 +1398,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_spansion, &spi_nor_sst, &spi_nor_st, + &spi_nor_winbond, }; static const struct flash_info * @@ -2991,33 +2941,6 @@ int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable) return ret; } -static int winbond_set_4byte(struct spi_nor *nor, bool enable) -{ - int ret; - - ret = en4_ex4_set_4byte(nor, enable); - if (ret || enable) - return ret; - - /* - * On Winbond W25Q256FV, leaving 4byte mode causes the Extended Address - * Register to be set to 1, so all 3-byte-address reads come from the - * second 16M. - * We must clear the register to enable normal behavior. - */ - write_enable(nor); - nor->cmd_buf[0] = 0; - nor->write_reg(nor, SPINOR_OP_WREAR, nor->cmd_buf, 1); - write_disable(nor); - - return ret; -} - -static void winbond_post_sfdp_fixups(struct spi_nor *nor) -{ - nor->set_4byte = winbond_set_4byte; -} - static int s3an_post_sfdp_fixups(struct spi_nor *nor) { int ret; @@ -3074,15 +2997,6 @@ spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, nor->manufacturer->fixups->post_sfdp) return nor->manufacturer->fixups->post_sfdp(nor, params); - switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_WINBOND: - winbond_post_sfdp_fixups(nor); - break; - - default: - break; - } - if (nor->info->flags & SPI_S3AN) return s3an_post_sfdp_fixups(nor); diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 298b4a855774..9030bb49c2a7 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -346,6 +346,7 @@ extern const struct spi_nor_manufacturer spi_nor_micron; extern const struct spi_nor_manufacturer spi_nor_spansion; extern const struct spi_nor_manufacturer spi_nor_sst; extern const struct spi_nor_manufacturer spi_nor_st; +extern const struct spi_nor_manufacturer spi_nor_winbond; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c new file mode 100644 index 000000000000..fceaf8392a16 --- /dev/null +++ b/drivers/mtd/spi-nor/winbond.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info winbond_parts[] = { + { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, + { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, + { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, + { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, + { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, + { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, + { + "w25q16dw", + INFO(0xef6015, 0, 64 * 1024, 32, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, + { "w25q20cl", INFO(0xef4012, 0, 64 * 1024, 4, SECT_4K) }, + { "w25q20bw", INFO(0xef5012, 0, 64 * 1024, 4, SECT_4K) }, + { "w25q20ew", INFO(0xef6012, 0, 64 * 1024, 4, SECT_4K) }, + { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, + { + "w25q32dw", + INFO(0xef6016, 0, 64 * 1024, 64, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "w25q32jv", + INFO(0xef7016, 0, 64 * 1024, 64, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, + { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { + "w25q64dw", + INFO(0xef6017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "w25q128fw", + INFO(0xef6018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { + "w25q128jv", + INFO(0xef7018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, + { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, + { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, + { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, + { + "w25q256", + INFO(0xef4019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "w25m512jv", + INFO(0xef7119, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) + }, +}; + +static int winbond_set_4byte(struct spi_nor *nor, bool enable) +{ + int ret; + + ret = en4_ex4_set_4byte(nor, enable); + if (ret || enable) + return ret; + + /* + * On Winbond W25Q256FV, leaving 4byte mode causes the Extended Address + * Register to be set to 1, so all 3-byte-address reads come from the + * second 16M. + * We must clear the register to enable normal behavior. + */ + write_enable(nor); + nor->cmd_buf[0] = 0; + nor->write_reg(nor, SPINOR_OP_WREAR, nor->cmd_buf, 1); + write_disable(nor); + + return ret; +} + +static int winbond_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + nor->set_4byte = winbond_set_4byte; + + return 0; +} + +static const struct spi_nor_fixups winbond_fixups = { + .post_sfdp = winbond_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_winbond = { + .name = "winbond", + .parts = winbond_parts, + .nparts = ARRAY_SIZE(winbond_parts), + .fixups = &winbond_fixups, +}; From patchwork Fri Dec 7 09:26:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009298 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="CaaBhhTm"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6vS25XNz9s3q for ; Fri, 7 Dec 2018 20:42:28 +1100 (AEDT) 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=2DvNuKQ8BUXyV4omHQp3hbUspSbhJRQzm7jHbyt5/Bw=; b=CaaBhhTmvvACRc6cU77LGd6Fz4 x5vFOCGMXs5SRkeXoAkoIJvkoP75HifkGu2l+1A4RRx84o2pQ22r2yEYU5GVGdsLT0+yCujnmPGEH 5uIDq6M4HjJjBjD6SQTDSxmT3jcO6ZQsXjKa/3U0LimpzttDC0CBF1SyLkN0yPFjVkk6y+MaoBK6J AGJfH81NQoZ/EA/8AEKLHhxDesQLQ/mUKmyZBiiN9s3NATPTiqbftaoKwzJ1v2gT2z4e3hO/0Q5kb dpaOJwy78XtiHvR8i5OtIY4vynehAHU7FGs9AUGhjVPYJCjm8wiUIUBpRZwALIZ1VzRnJtmMjE1zm 5WD0p0Xw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCe5-0006dd-UK; Fri, 07 Dec 2018 09:42:05 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPz-0000zg-A9 for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:57 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 5C8A620E23; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id E743520E2A; Fri, 7 Dec 2018 10:26:43 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 29/34] mtd: spi-nor: Move Catalyst bits out of core.c Date: Fri, 7 Dec 2018 10:26:32 +0100 Message-Id: <20181207092637.18687-30-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012731_917289_D239370B X-CRM114-Status: GOOD ( 15.56 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Catalyst chips, and move the Catalyst definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/catalyst.c | 39 +++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/core.c | 8 +------ drivers/mtd/spi-nor/internals.h | 1 + 4 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 drivers/mtd/spi-nor/catalyst.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index f74628184261..1b5fcf20f6fc 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 spi-nor-objs := core.o spi-nor-objs += atmel.o +spi-nor-objs += catalyst.o spi-nor-objs += eon.o spi-nor-objs += esmt.o spi-nor-objs += everspin.o diff --git a/drivers/mtd/spi-nor/catalyst.c b/drivers/mtd/spi-nor/catalyst.c new file mode 100644 index 000000000000..697ae07e1068 --- /dev/null +++ b/drivers/mtd/spi-nor/catalyst.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info catalyst_parts[] = { + { + "cat25c11", + CAT25_INFO(16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "cat25c03", + CAT25_INFO(32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "cat25c09", + CAT25_INFO(128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "cat25c17", + CAT25_INFO(256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, + { + "cat25128", + CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) + }, +}; + +const struct spi_nor_manufacturer spi_nor_catalyst = { + .name = "catalyst", + .parts = catalyst_parts, + .nparts = ARRAY_SIZE(catalyst_parts), +}; diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index ff6485473a90..501322e87dbe 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1364,13 +1364,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Catalyst / On Semiconductor -- non-JEDEC */ - { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - /* Xilinx S3AN Internal Flash */ { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, @@ -1386,6 +1379,7 @@ static const struct flash_info spi_nor_ids[] = { static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_atmel, + &spi_nor_catalyst, &spi_nor_eon, &spi_nor_esmt, &spi_nor_everspin, diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 9030bb49c2a7..2b329b8ea6ef 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -334,6 +334,7 @@ struct spi_nor_manufacturer { /* Manufacturer drivers. */ extern const struct spi_nor_manufacturer spi_nor_atmel; +extern const struct spi_nor_manufacturer spi_nor_catalyst; extern const struct spi_nor_manufacturer spi_nor_eon; extern const struct spi_nor_manufacturer spi_nor_esmt; extern const struct spi_nor_manufacturer spi_nor_everspin; From patchwork Fri Dec 7 09:26:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009295 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="fBL3PNjM"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="N0dlSiMd"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6tm1CSPz9s3q for ; Fri, 7 Dec 2018 20:41:52 +1100 (AEDT) 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=vjxFrGCN8BcWNx1Gy9ngxqCEQZ69WRFy8DnJ7v5GM0s=; b=fBL3PNjMaJlhKFEnBQYWBL2dUo QgpSfTI5j1NB62V68oYsTtJccQDd1vUARUJ6jv3AQsGhLQ+4vXacTTzAgajHWNkbGyKKhU4Y7TCu3 xtmWaSw5Dr2b0sPJbXpXt/G0s5/u/r22+g7fSqyy+QegjAG41IDoq/hqG5mkIYaHgkATPjlLgeJOx pXtJOJvnnZ5pIMwdumYD/aph9qU3EuX/K+Unxiqa8l662ogFVTVM45yixT6ueGxGQrCPrKdxwmtci +WmzDswFs+blN5sPAcZvZrV/9+p3YDKdEG9Nq0Q9INwJg+jMKOdShl/PUxQFr/jEFYtaIDvxR6ZVi NwljYvAA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCdo-0006Lj-FP; Fri, 07 Dec 2018 09:41:48 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQA-0001my-AG for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:42 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=YfY4562ZUsMX2gk+rQYlq7+ztH/xvbQdYm5nts1l3Ig=; b=N0dlSiMdcv+Z4crO2XM/oqRH1 7rY5c9ml1UioheU7wLgQfdq5Ykv7eURiGRqNtynj+cAsSthYrEcz9TzOS2W0yUCWCpMn8a5qTiWKP h8GH1OB7B9uvbLfON0t50D1w4B6hGyJJ8gcj2EJpHPvYj0EkFXy/cZTsTEVve1vvK4WiBxpnDx/aM b8oj1tB9ox/4SpDHNkzD14QEi0hO/tKzoWhUguRKzaG1nzrZXlCxdXPmvC3muCT0SNqS1T4OC2JEk xU9yKRPoMMU4mw6er3rFfpfMEhQcIxwiUHweuZ1Zlrn2nmnfNvVO1siU9IM5/9ShW3Df4pO6KmWML 5IFaF5g/Q==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ2-0005hV-Me for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:38 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 67AAB20E25; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 2611F20E2C; Fri, 7 Dec 2018 10:26:44 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 30/34] mtd: spi-nor: Move Xilinx bits out of core.c Date: Fri, 7 Dec 2018 10:26:33 +0100 Message-Id: <20181207092637.18687-31-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042735_041188_A870A140 X-CRM114-Status: GOOD ( 27.40 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for Xilinx chips, and move the Xilinx definitions outside of core.c. While at it, remove the SPI_S3AN flag which is now useless. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 106 ++++---------------------------- drivers/mtd/spi-nor/internals.h | 13 +--- drivers/mtd/spi-nor/xilinx.c | 97 +++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 105 deletions(-) create mode 100644 drivers/mtd/spi-nor/xilinx.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 1b5fcf20f6fc..9b89f3b4401a 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -14,6 +14,7 @@ spi-nor-objs += micron-st.o spi-nor-objs += spansion.o spi-nor-objs += sst.o spi-nor-objs += winbond.o +spi-nor-objs += xilinx.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 501322e87dbe..c14543fd4af6 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -358,26 +358,6 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) mutex_unlock(&nor->lock); } -/* - * This code converts an address to the Default Address Mode, that has non - * power of two page sizes. We must support this mode because it is the default - * mode supported by Xilinx tools, it can access the whole flash area and - * changing over to the Power-of-two mode is irreversible and corrupts the - * original data. - * Addr can safely be unsigned int, the biggest S3AN device is smaller than - * 4 MiB. - */ -static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) -{ - u32 offset, page; - - offset = addr % nor->page_size; - page = addr / nor->page_size; - page <<= (nor->page_size > 512) ? 10 : 9; - - return page | offset; -} - static u32 spi_nor_convert_addr(struct spi_nor *nor, u32 addr) { if (!nor->convert_addr) @@ -1364,13 +1344,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* Xilinx S3AN Internal Flash */ - { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, - { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, - { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, - { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, - { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, - /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, @@ -1393,6 +1366,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_sst, &spi_nor_st, &spi_nor_winbond, + &spi_nor_xilinx, }; static const struct flash_info * @@ -2935,81 +2909,25 @@ int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable) return ret; } -static int s3an_post_sfdp_fixups(struct spi_nor *nor) -{ - int ret; - u8 val; - - ret = nor->read_reg(nor, SPINOR_OP_XRDSR, &val, 1); - if (ret < 0) { - dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret); - return ret; - } - - /* - * We choose the opcodes we want to use, so let's add - * SNOR_F_SKIP_SETUP to prevent spi_nor_setup() from changing - * them behind our back. - */ - nor->flags |= SNOR_F_SKIP_SETUP; - nor->erase_opcode = SPINOR_OP_XSE; - nor->program_opcode = SPINOR_OP_XPP; - nor->read_opcode = SPINOR_OP_READ; - nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; - - /* - * This flashes have a page size of 264 or 528 bytes (known as - * Default addressing mode). It can be changed to a more standard - * Power of two mode where the page size is 256/512. This comes - * with a price: there is 3% less of space, the data is corrupted - * and the page size cannot be changed back to default addressing - * mode. - * - * The current addressing mode can be read from the XRDSR register - * and should not be changed, because is a destructive operation. - */ - if (val & XSR_PAGESIZE) { - /* Flash in Power of 2 mode */ - nor->page_size = (nor->page_size == 264) ? 256 : 512; - nor->mtd.writebufsize = nor->page_size; - nor->mtd.size = 8 * nor->page_size * nor->info->n_sectors; - nor->mtd.erasesize = 8 * nor->page_size; - } else { - /* Flash in Default addressing mode */ - nor->convert_addr = s3an_convert_addr; - } - - return 0; -} - - -static int -spi_nor_manufacturer_post_sfdp_fixups(struct spi_nor *nor, - struct spi_nor_flash_parameter *params) -{ - if (nor->manufacturer && nor->manufacturer->fixups && - nor->manufacturer->fixups->post_sfdp) - return nor->manufacturer->fixups->post_sfdp(nor, params); - - if (nor->info->flags & SPI_S3AN) - return s3an_post_sfdp_fixups(nor); - - return 0; -} - static int spi_nor_post_sfdp_fixups(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { int ret; - ret = spi_nor_manufacturer_post_sfdp_fixups(nor, params); - if (ret) - return ret; + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->post_sfdp) { + ret = nor->manufacturer->fixups->post_sfdp(nor, params); + if (ret) + return ret; + } - if (nor->info->fixups && nor->info->fixups->post_sfdp) + if (nor->info->fixups && nor->info->fixups->post_sfdp) { ret = nor->info->fixups->post_sfdp(nor, params); + if (ret) + return ret; + } - return ret; + return 0; } static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 2b329b8ea6ef..c24c9eb1c2e2 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -245,16 +245,6 @@ struct flash_info { #define SPI_NOR_XSR_RDY BIT(10) /* * S3AN flashes have specific opcode to * read the status register. - * Flags SPI_NOR_XSR_RDY and SPI_S3AN - * use the same bit as one implies the - * other, but we will get rid of - * SPI_S3AN soon. - */ -#define SPI_S3AN BIT(10) /* - * Xilinx Spartan 3AN In-System Flash - * (MFR cannot be used for probing - * because it has the same value as - * ATMEL flashes) */ #define SPI_NOR_4B_OPCODES BIT(11) /* * Use dedicated 4byte address op codes @@ -316,7 +306,7 @@ struct flash_info { .n_sectors = (_n_sectors), \ .page_size = _page_size, \ .addr_width = 3, \ - .flags = SPI_NOR_NO_FR | SPI_S3AN, + .flags = SPI_NOR_NO_FR | SPI_NOR_XSR_RDY, /** * struct spi_nor_manufacturer - SPI NOR manufacturer object @@ -348,6 +338,7 @@ extern const struct spi_nor_manufacturer spi_nor_spansion; extern const struct spi_nor_manufacturer spi_nor_sst; extern const struct spi_nor_manufacturer spi_nor_st; extern const struct spi_nor_manufacturer spi_nor_winbond; +extern const struct spi_nor_manufacturer spi_nor_xilinx; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c new file mode 100644 index 000000000000..f64b5952a9aa --- /dev/null +++ b/drivers/mtd/spi-nor/xilinx.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info xilinx_parts[] = { + { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, + { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, + { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, + { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, + { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, +}; + +/* + * This code converts an address to the Default Address Mode, that has non + * power of two page sizes. We must support this mode because it is the default + * mode supported by Xilinx tools, it can access the whole flash area and + * changing over to the Power-of-two mode is irreversible and corrupts the + * original data. + * Addr can safely be unsigned int, the biggest S3AN device is smaller than + * 4 MiB. + */ +static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) +{ + u32 offset, page; + + offset = addr % nor->page_size; + page = addr / nor->page_size; + page <<= (nor->page_size > 512) ? 10 : 9; + + return page | offset; +} + +static int xilinx_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + int ret; + u8 val; + + ret = nor->read_reg(nor, SPINOR_OP_XRDSR, &val, 1); + if (ret < 0) { + dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret); + return ret; + } + + /* + * We choose the opcodes we want to use, so let's add + * SNOR_F_SKIP_SETUP to prevent spi_nor_setup() from changing + * them behind our back. + */ + nor->flags |= SNOR_F_SKIP_SETUP; + nor->erase_opcode = SPINOR_OP_XSE; + nor->program_opcode = SPINOR_OP_XPP; + nor->read_opcode = SPINOR_OP_READ; + nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; + + /* + * This flashes have a page size of 264 or 528 bytes (known as + * Default addressing mode). It can be changed to a more standard + * Power of two mode where the page size is 256/512. This comes + * with a price: there is 3% less of space, the data is corrupted + * and the page size cannot be changed back to default addressing + * mode. + * + * The current addressing mode can be read from the XRDSR register + * and should not be changed, because is a destructive operation. + */ + if (val & XSR_PAGESIZE) { + /* Flash in Power of 2 mode */ + nor->page_size = (nor->page_size == 264) ? 256 : 512; + nor->mtd.writebufsize = nor->page_size; + nor->mtd.size = 8 * nor->page_size * nor->info->n_sectors; + nor->mtd.erasesize = 8 * nor->page_size; + } else { + /* Flash in Default addressing mode */ + nor->convert_addr = s3an_convert_addr; + } + + return 0; +} + +static const struct spi_nor_fixups xilinx_fixups = { + .post_sfdp = xilinx_post_sfdp_fixups, +}; + +const struct spi_nor_manufacturer spi_nor_xilinx = { + .name = "xilinx", + .parts = xilinx_parts, + .nparts = ARRAY_SIZE(xilinx_parts), + .fixups = &xilinx_fixups, +}; From patchwork Fri Dec 7 09:26:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009284 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="P24SY9Yl"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="DXJlqsW6"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6hC4ymGz9s3q for ; Fri, 7 Dec 2018 20:32:43 +1100 (AEDT) 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=MbjsrStpxbV/M4GaA2nPaARt3hi5UYG6ytv1F46STno=; b=P24SY9Ylpm4k/zWQz+zo88HJF7 bl1vRG9lDZgS9JBa4Z8hwiLW/fmJxovR3fl1FkLyX8k1rvxMgcRlPTrIj9E4vN4/gJxfoyQ7J/mBI eQbvaupa6y/+QPwAukJw5bDTw9tV4djuinJ+r7jO5/ppiLpg7m6oe4LOZlP5W1NzvHPt8jcltWLSx Zphha2/Pui7GmKZ4m1m9X4i/rvOP/14PJWelUFDpP9Pec/YVCr04d2E/OwSCYG3yfrRVkCSZOOpZm /2exn0IEp97fslT75Ie10xJmU61EcR0tmxPCPt44ln1MNbCJmccOUuLey/2uoUWHv2ABsKEcqPNDR 1yJ9a9mA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCUt-0007kL-PG; Fri, 07 Dec 2018 09:32:35 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ9-0001n4-5i for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:41 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=E9xvw9fReaGshAprw6J2UomvAs3uK4GFMkw3l6z64PU=; b=DXJlqsW60uzTbxHqaOjP39p+b xHB7TRf00zzFlNkK6FugSHFMaNaUTfz0973BqIfJDl2vZ31q8XixaeTAR7B3mMDiSZiABtXk/lFLI iDDHREdI17T5UD+U/5zC6I01BwdjosJCi4IeRwFPEhKEIia52tNQZBy2zl9AUNNkDqvr6vu+B1yEt OLfEREUI8sNFLcJOkjsfALDe76CpODCPZssMZCI/URUQZ8HuCzazOKsNmiL9DXhlq9IFI01JJPSNH lfiiX2KR4Zvu2L4jvJ0ihutLribU25uaX6/BM9sGHiDHUZ207xORxyE4SEj8B4xtpgM08uUwiQlLC Ex1Zp3KwQ==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ4-0005hW-W3 for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:38 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 77A9020E26; Fri, 7 Dec 2018 10:27:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 5DAF020E2E; Fri, 7 Dec 2018 10:26:44 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 31/34] mtd: spi-nor: Move XMC bits out of core.c Date: Fri, 7 Dec 2018 10:26:34 +0100 Message-Id: <20181207092637.18687-32-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042737_308282_C3EE2E18 X-CRM114-Status: GOOD ( 15.30 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Create a SPI NOR manufacturer driver for XMC chips, and move the XMC definitions outside of core.c. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 1 + drivers/mtd/spi-nor/core.c | 4 +--- drivers/mtd/spi-nor/internals.h | 1 + drivers/mtd/spi-nor/xmc.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 drivers/mtd/spi-nor/xmc.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 9b89f3b4401a..07ded3a76623 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -15,6 +15,7 @@ spi-nor-objs += spansion.o spi-nor-objs += sst.o spi-nor-objs += winbond.o spi-nor-objs += xilinx.o +spi-nor-objs += xmc.o obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o obj-$(CONFIG_MTD_SPI_NOR) += controllers/ diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index c14543fd4af6..ffae10327de2 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1344,9 +1344,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) * old entries may be missing 4K flag. */ static const struct flash_info spi_nor_ids[] = { - /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ - { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { }, }; @@ -1367,6 +1364,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_st, &spi_nor_winbond, &spi_nor_xilinx, + &spi_nor_xmc, }; static const struct flash_info * diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index c24c9eb1c2e2..96b08b53f8f6 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -339,6 +339,7 @@ extern const struct spi_nor_manufacturer spi_nor_sst; extern const struct spi_nor_manufacturer spi_nor_st; extern const struct spi_nor_manufacturer spi_nor_winbond; extern const struct spi_nor_manufacturer spi_nor_xilinx; +extern const struct spi_nor_manufacturer spi_nor_xmc; /* Core helpers. */ int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); diff --git a/drivers/mtd/spi-nor/xmc.c b/drivers/mtd/spi-nor/xmc.c new file mode 100644 index 000000000000..233be0661ea8 --- /dev/null +++ b/drivers/mtd/spi-nor/xmc.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include + +#include "internals.h" + +static const struct flash_info xmc_parts[] = { + { + "XM25QH64A", + INFO(0x207017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, + { + "XM25QH128A", + INFO(0x207018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + }, +}; + +const struct spi_nor_manufacturer spi_nor_xmc = { + .name = "xmc", + .parts = xmc_parts, + .nparts = ARRAY_SIZE(xmc_parts), +}; From patchwork Fri Dec 7 09:26:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009297 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="pJGlb3oa"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6vP3x7tz9s3q for ; Fri, 7 Dec 2018 20:42:25 +1100 (AEDT) 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=fR+J/xWsLEeJNcU2lSmeY4R91s61JLca+VdRKhHRCsU=; b=pJGlb3oaoK6jVuUa4bdAvjp5uJ oTZV/8C7EldbvUB0GC50HS3/R5VgwrJHe+l7EEHoDTz0tfA2MGLz8q5Qkg8ujh5H37/g0+iEcQ/0q f8stcHjQ4/5ZQo/iuBh57L66eks+WsPwg1fhyCy0Y64jl0qYLzGcHHQZGaj320qvV5TpoZzurSGot Z/57UfQxOhX0R3jJL7OqrG1wyBcKOQp/TIoaHUXJCw+wSlfK76H16OZD/6hs7kM42Hah52grsg8Wu 94yCOlWeiIy6+T+PHPCnqbc5P/UdGioEHgiDPRjhWs6sNURPRV5VyF5P6MeTl9X6PHonpLx7d1QlU XWtWBgOw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCeD-0006kg-F6; Fri, 07 Dec 2018 09:42:13 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPz-0000zd-Eb for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:57 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 073B320E22; Fri, 7 Dec 2018 10:27:03 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 933DE20E2F; Fri, 7 Dec 2018 10:26:44 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 32/34] mtd: spi-nor: Get rid of the now empty spi_nor_ids[] table Date: Fri, 7 Dec 2018 10:26:35 +0100 Message-Id: <20181207092637.18687-33-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012732_025172_CCBE387D X-CRM114-Status: GOOD ( 11.66 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org All entries have been moved to manufacturer drivers. Get rid of this empty table. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/core.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index ffae10327de2..6ed562bddddb 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1332,21 +1332,6 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor) return 0; } -/* NOTE: double check command sets and memory organization when you add - * more nor chips. This current list focusses on newer chips, which - * have been converging on command sets which including JEDEC ID. - * - * All newly added entries should describe *hardware* and should use SECT_4K - * (or SECT_4K_PMC) if hardware supports erasing 4 KiB sectors. For usage - * scenarios excluding small sectors there is config option that can be - * disabled: CONFIG_MTD_SPI_NOR_USE_4K_SECTORS. - * For historical (and compatibility) reasons (before we got above config) some - * old entries may be missing 4K flag. - */ -static const struct flash_info spi_nor_ids[] = { - { }, -}; - static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_atmel, &spi_nor_catalyst, @@ -1404,11 +1389,6 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) } } - info = spi_nor_search_part_by_id(spi_nor_ids, - ARRAY_SIZE(spi_nor_ids) - 1, id); - if (info) - return info; - dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", id[0], id[1], id[2]); return ERR_PTR(-ENODEV); @@ -2933,11 +2913,6 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, { unsigned int i, j; - for (i = 0; i < ARRAY_SIZE(spi_nor_ids) - 1; i++) { - if (!strcmp(name, spi_nor_ids[i].name)) - return &spi_nor_ids[i]; - } - for (i = 0; i < ARRAY_SIZE(manufacturers); i++) { for (j = 0; j < manufacturers[i]->nparts; j++) { if (!strcmp(name, manufacturers[i]->parts[j].name)) { From patchwork Fri Dec 7 09:26:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009299 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="GK+c7cgn"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6vY49sHz9s55 for ; Fri, 7 Dec 2018 20:42:33 +1100 (AEDT) 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=4/0hEqymj4yQrzjoE2cOBe9VYpASDwRk5dM/J///uhk=; b=GK+c7cgnA3GmlPQoxPP+5Vcuv7 oVkqEERdkj3IaP5po6NmTWuudLEuNXWt6scs6y+J0ylmCubtkyxcX3PT54tVufBaNrCBtZRUHoPGl KFpCkKIUY8PIrXx/dAXbq3vJTKJw/I0CPBOgeqtaFz7dnLesCwphxHbLKgEZAq6FkGYhr80LCv5kL gg0MQNkLEAlDIQsHr++rEbPFz04XCTFFB4rCQkBK0Ii4SOdYKC6HWRoDFc8hu5AHKV2BqjD/Th9pj tWhw4edO43ZCijrSzNBlYbUFfhzHg3hitLSjp0VB06VTx0CNg6cGzf7jug9IwCFnQn4I41cOi/S5I 34f37ARg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCeM-0006v3-Oz; Fri, 07 Dec 2018 09:42:23 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPz-000102-Pp for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:28:19 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 1F85720E27; Fri, 7 Dec 2018 10:27:03 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id CD1EC20E30; Fri, 7 Dec 2018 10:26:44 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 33/34] mtd: spi-nor: Move SFDP parsing code out of core.c Date: Fri, 7 Dec 2018 10:26:36 +0100 Message-Id: <20181207092637.18687-34-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012732_681811_28BEFD51 X-CRM114-Status: GOOD ( 23.46 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org It make the core file a bit smaller and provide better separation between the SFDP parsing and core logic. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/Makefile | 2 +- drivers/mtd/spi-nor/core.c | 870 +------------------------------- drivers/mtd/spi-nor/internals.h | 15 + drivers/mtd/spi-nor/sfdp.c | 859 +++++++++++++++++++++++++++++++ 4 files changed, 885 insertions(+), 861 deletions(-) create mode 100644 drivers/mtd/spi-nor/sfdp.c diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 07ded3a76623..1ae2ef1fbfc3 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -spi-nor-objs := core.o +spi-nor-objs := core.o sfdp.o spi-nor-objs += atmel.o spi-nor-objs += catalyst.o spi-nor-objs += eon.o diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 6ed562bddddb..9665f4d3ec19 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -465,7 +464,7 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map, * * Return: the next spi nor region or NULL if last region. */ -static struct spi_nor_erase_region * +struct spi_nor_erase_region * spi_nor_region_next(struct spi_nor_erase_region *region) { if (spi_nor_region_is_last(region)) @@ -1211,7 +1210,7 @@ static int legacy_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int sr2_bit1_no_read_quad_enable(struct spi_nor *nor) +int sr2_bit1_no_read_quad_enable(struct spi_nor *nor) { u8 sr_cr[2]; int ret; @@ -1241,7 +1240,7 @@ static int sr2_bit1_no_read_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int sr2_bit1_read_quad_enable(struct spi_nor *nor) +int sr2_bit1_read_quad_enable(struct spi_nor *nor) { struct device *dev = nor->dev; u8 sr_cr[2]; @@ -1293,7 +1292,7 @@ static int sr2_bit1_read_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -static int sr2_bit7_quad_enable(struct spi_nor *nor) +int sr2_bit7_quad_enable(struct spi_nor *nor) { u8 sr2; int ret; @@ -1538,7 +1537,7 @@ static int spi_nor_hwcaps2cmd(u32 hwcaps, const int table[][2], size_t size) return -EINVAL; } -static int spi_nor_hwcaps_read2cmd(u32 hwcaps) +int spi_nor_hwcaps_read2cmd(u32 hwcaps) { static const int hwcaps_read2cmd[][2] = { { SNOR_HWCAPS_READ, SNOR_CMD_READ }, @@ -1594,7 +1593,7 @@ static int spi_nor_hwcaps_pp2cmd(u32 hwcaps) * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_read_raw(struct spi_nor *nor, u32 addr, size_t len, u8 *buf) +int spi_nor_read_raw(struct spi_nor *nor, u32 addr, size_t len, u8 *buf) { int ret; @@ -1612,189 +1611,14 @@ static int spi_nor_read_raw(struct spi_nor *nor, u32 addr, size_t len, u8 *buf) return 0; } -/** - * spi_nor_read_sfdp() - read Serial Flash Discoverable Parameters. - * @nor: pointer to a 'struct spi_nor' - * @addr: offset in the SFDP area to start reading data from - * @len: number of bytes to read - * @buf: buffer where the SFDP data are copied into (dma-safe memory) - * - * Whatever the actual numbers of bytes for address and dummy cycles are - * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always - * followed by a 3-byte address and 8 dummy clock cycles. - * - * Return: 0 on success, -errno otherwise. - */ -static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr, - size_t len, void *buf) -{ - u8 addr_width, read_opcode, read_dummy; - int ret; - - read_opcode = nor->read_opcode; - addr_width = nor->addr_width; - read_dummy = nor->read_dummy; - - nor->read_opcode = SPINOR_OP_RDSFDP; - nor->addr_width = 3; - nor->read_dummy = 8; - - ret = spi_nor_read_raw(nor, addr, len, buf); - - nor->read_opcode = read_opcode; - nor->addr_width = addr_width; - nor->read_dummy = read_dummy; - - return ret; -} - -/** - * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters. - * @nor: pointer to a 'struct spi_nor' - * @addr: offset in the SFDP area to start reading data from - * @len: number of bytes to read - * @buf: buffer where the SFDP data are copied into - * - * Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not - * guaranteed to be dma-safe. - * - * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp() - * otherwise. - */ -static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr, - size_t len, void *buf) -{ - void *dma_safe_buf; - int ret; - - dma_safe_buf = kmalloc(len, GFP_KERNEL); - if (!dma_safe_buf) - return -ENOMEM; - - ret = spi_nor_read_sfdp(nor, addr, len, dma_safe_buf); - memcpy(buf, dma_safe_buf, len); - kfree(dma_safe_buf); - - return ret; -} - -/* Fast Read settings. */ - -static void -spi_nor_set_read_settings_from_bfpt(struct spi_nor_read_command *read, - u16 half, - enum spi_nor_protocol proto) -{ - read->num_mode_clocks = (half >> 5) & 0x07; - read->num_wait_states = (half >> 0) & 0x1f; - read->opcode = (half >> 8) & 0xff; - read->proto = proto; -} - -struct sfdp_bfpt_read { - /* The Fast Read x-y-z hardware capability in params->hwcaps.mask. */ - u32 hwcaps; - - /* - * The bit in BFPT DWORD tells us - * whether the Fast Read x-y-z command is supported. - */ - u32 supported_dword; - u32 supported_bit; - - /* - * The half-word at offset in BFPT DWORD - * encodes the op code, the number of mode clocks and the number of wait - * states to be used by Fast Read x-y-z command. - */ - u32 settings_dword; - u32 settings_shift; - - /* The SPI protocol for this Fast Read x-y-z command. */ - enum spi_nor_protocol proto; -}; - -static const struct sfdp_bfpt_read sfdp_bfpt_reads[] = { - /* Fast Read 1-1-2 */ - { - SNOR_HWCAPS_READ_1_1_2, - BFPT_DWORD(1), BIT(16), /* Supported bit */ - BFPT_DWORD(4), 0, /* Settings */ - SNOR_PROTO_1_1_2, - }, - - /* Fast Read 1-2-2 */ - { - SNOR_HWCAPS_READ_1_2_2, - BFPT_DWORD(1), BIT(20), /* Supported bit */ - BFPT_DWORD(4), 16, /* Settings */ - SNOR_PROTO_1_2_2, - }, - - /* Fast Read 2-2-2 */ - { - SNOR_HWCAPS_READ_2_2_2, - BFPT_DWORD(5), BIT(0), /* Supported bit */ - BFPT_DWORD(6), 16, /* Settings */ - SNOR_PROTO_2_2_2, - }, - - /* Fast Read 1-1-4 */ - { - SNOR_HWCAPS_READ_1_1_4, - BFPT_DWORD(1), BIT(22), /* Supported bit */ - BFPT_DWORD(3), 16, /* Settings */ - SNOR_PROTO_1_1_4, - }, - - /* Fast Read 1-4-4 */ - { - SNOR_HWCAPS_READ_1_4_4, - BFPT_DWORD(1), BIT(21), /* Supported bit */ - BFPT_DWORD(3), 0, /* Settings */ - SNOR_PROTO_1_4_4, - }, - - /* Fast Read 4-4-4 */ - { - SNOR_HWCAPS_READ_4_4_4, - BFPT_DWORD(5), BIT(4), /* Supported bit */ - BFPT_DWORD(7), 16, /* Settings */ - SNOR_PROTO_4_4_4, - }, -}; - -struct sfdp_bfpt_erase { - /* - * The half-word at offset in DWORD encodes the - * op code and erase sector size to be used by Sector Erase commands. - */ - u32 dword; - u32 shift; -}; - -static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { - /* Erase Type 1 in DWORD8 bits[15:0] */ - {BFPT_DWORD(8), 0}, - - /* Erase Type 2 in DWORD8 bits[31:16] */ - {BFPT_DWORD(8), 16}, - - /* Erase Type 3 in DWORD9 bits[15:0] */ - {BFPT_DWORD(9), 0}, - - /* Erase Type 4 in DWORD9 bits[31:16] */ - {BFPT_DWORD(9), 16}, -}; - /** * spi_nor_set_erase_type() - set a SPI NOR erase type * @erase: pointer to a structure that describes a SPI NOR erase type * @size: the size of the sector/block erased by the erase type * @opcode: the SPI command op code to erase the sector/block */ -static void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, - u32 size, u8 opcode) +void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size, + u8 opcode) { erase->size = size; erase->opcode = opcode; @@ -1803,82 +1627,6 @@ static void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, erase->size_mask = (1 << erase->size_shift) - 1; } -/** - * spi_nor_set_erase_settings_from_bfpt() - set erase type settings from BFPT - * @erase: pointer to a structure that describes a SPI NOR erase type - * @size: the size of the sector/block erased by the erase type - * @opcode: the SPI command op code to erase the sector/block - * @i: erase type index as sorted in the Basic Flash Parameter Table - * - * The supported Erase Types will be sorted at init in ascending order, with - * the smallest Erase Type size being the first member in the erase_type array - * of the spi_nor_erase_map structure. Save the Erase Type index as sorted in - * the Basic Flash Parameter Table since it will be used later on to - * synchronize with the supported Erase Types defined in SFDP optional tables. - */ -static void -spi_nor_set_erase_settings_from_bfpt(struct spi_nor_erase_type *erase, - u32 size, u8 opcode, u8 i) -{ - erase->idx = i; - spi_nor_set_erase_type(erase, size, opcode); -} - -/** - * spi_nor_map_cmp_erase_type() - compare the map's erase types by size - * @l: member in the left half of the map's erase_type array - * @r: member in the right half of the map's erase_type array - * - * Comparison function used in the sort() call to sort in ascending order the - * map's erase types, the smallest erase type size being the first member in the - * sorted erase_type array. - * - * Return: the result of @l->size - @r->size - */ -static int spi_nor_map_cmp_erase_type(const void *l, const void *r) -{ - const struct spi_nor_erase_type *left = l, *right = r; - - return left->size - right->size; -} - -/** - * spi_nor_regions_sort_erase_types() - sort erase types in each region - * @map: the erase map of the SPI NOR - * - * Function assumes that the erase types defined in the erase map are already - * sorted in ascending order, with the smallest erase type size being the first - * member in the erase_type array. It replicates the sort done for the map's - * erase types. Each region's erase bitmask will indicate which erase types are - * supported from the sorted erase types defined in the erase map. - * Sort the all region's erase type at init in order to speed up the process of - * finding the best erase command at runtime. - */ -static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) -{ - struct spi_nor_erase_region *region = map->regions; - struct spi_nor_erase_type *erase_type = map->erase_type; - int i; - u8 region_erase_mask, sorted_erase_mask; - - while (region) { - region_erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; - - /* Replicate the sort done for the map's erase types. */ - sorted_erase_mask = 0; - for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) - if (erase_type[i].size && - region_erase_mask & BIT(erase_type[i].idx)) - sorted_erase_mask |= BIT(i); - - /* Overwrite erase mask. */ - region->offset = (region->offset & ~SNOR_ERASE_TYPE_MASK) | - sorted_erase_mask; - - region = spi_nor_region_next(region); - } -} - /** * spi_nor_init_uniform_erase_map() - Initialize uniform erase map * @map: the erase map of the SPI NOR @@ -1886,8 +1634,8 @@ static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) * flash memory * @flash_size: the spi nor flash memory size */ -static void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, - u8 erase_mask, u64 flash_size) +void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, + u8 erase_mask, u64 flash_size) { /* Offset 0 with erase_mask and SNOR_LAST_REGION bit set */ map->uniform_region.offset = (erase_mask & SNOR_ERASE_TYPE_MASK) | @@ -1897,604 +1645,6 @@ static void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, map->uniform_erase_type = erase_mask; } -static int -spi_nor_post_bfpt_fixups(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) -{ - int ret; - - if (nor->manufacturer && nor->manufacturer->fixups && - nor->manufacturer->fixups->post_bfpt) { - ret = nor->manufacturer->fixups->post_bfpt(nor, bfpt_header, - bfpt, params); - if (ret) - return ret; - } - - if (nor->info->fixups && nor->info->fixups->post_bfpt) { - ret = nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, - params); - if (ret) - return ret; - } - - return 0; -} - -/** - * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. - * @nor: pointer to a 'struct spi_nor' - * @bfpt_header: pointer to the 'struct sfdp_parameter_header' describing - * the Basic Flash Parameter Table length and version - * @params: pointer to the 'struct spi_nor_flash_parameter' to be - * filled - * - * The Basic Flash Parameter Table is the main and only mandatory table as - * defined by the SFDP (JESD216) specification. - * It provides us with the total size (memory density) of the data array and - * the number of address bytes for Fast Read, Page Program and Sector Erase - * commands. - * For Fast READ commands, it also gives the number of mode clock cycles and - * wait states (regrouped in the number of dummy clock cycles) for each - * supported instruction op code. - * For Page Program, the page size is now available since JESD216 rev A, however - * the supported instruction op codes are still not provided. - * For Sector Erase commands, this table stores the supported instruction op - * codes and the associated sector sizes. - * Finally, the Quad Enable Requirements (QER) are also available since JESD216 - * rev A. The QER bits encode the manufacturer dependent procedure to be - * executed to set the Quad Enable (QE) bit in some internal register of the - * Quad SPI memory. Indeed the QE bit, when it exists, must be set before - * sending any Quad SPI command to the memory. Actually, setting the QE bit - * tells the memory to reassign its WP# and HOLD#/RESET# pins to functions IO2 - * and IO3 hence enabling 4 (Quad) I/O lines. - * - * Return: 0 on success, -errno otherwise. - */ -static int spi_nor_parse_bfpt(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - struct spi_nor_flash_parameter *params) -{ - struct spi_nor_erase_map *map = &nor->erase_map; - struct spi_nor_erase_type *erase_type = map->erase_type; - struct sfdp_bfpt bfpt; - size_t len; - int i, cmd, err; - u32 addr; - u16 half; - u8 erase_mask; - - /* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs. */ - if (bfpt_header->length < BFPT_DWORD_MAX_JESD216) - return -EINVAL; - - /* Read the Basic Flash Parameter Table. */ - len = min_t(size_t, sizeof(bfpt), - bfpt_header->length * sizeof(u32)); - addr = SFDP_PARAM_HEADER_PTP(bfpt_header); - memset(&bfpt, 0, sizeof(bfpt)); - err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt); - if (err < 0) - return err; - - /* Fix endianness of the BFPT DWORDs. */ - for (i = 0; i < BFPT_DWORD_MAX; i++) - bfpt.dwords[i] = le32_to_cpu(bfpt.dwords[i]); - - /* Number of address bytes. */ - switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) { - case BFPT_DWORD1_ADDRESS_BYTES_3_ONLY: - nor->addr_width = 3; - break; - - case BFPT_DWORD1_ADDRESS_BYTES_4_ONLY: - nor->addr_width = 4; - break; - - default: - break; - } - - /* Flash Memory Density (in bits). */ - params->size = bfpt.dwords[BFPT_DWORD(2)]; - if (params->size & BIT(31)) { - params->size &= ~BIT(31); - - /* - * Prevent overflows on params->size. Anyway, a NOR of 2^64 - * bits is unlikely to exist so this error probably means - * the BFPT we are reading is corrupted/wrong. - */ - if (params->size > 63) - return -EINVAL; - - params->size = 1ULL << params->size; - } else { - params->size++; - } - params->size >>= 3; /* Convert to bytes. */ - - /* Fast Read settings. */ - for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_reads); i++) { - const struct sfdp_bfpt_read *rd = &sfdp_bfpt_reads[i]; - struct spi_nor_read_command *read; - - if (!(bfpt.dwords[rd->supported_dword] & rd->supported_bit)) { - params->hwcaps.mask &= ~rd->hwcaps; - continue; - } - - params->hwcaps.mask |= rd->hwcaps; - cmd = spi_nor_hwcaps_read2cmd(rd->hwcaps); - read = ¶ms->reads[cmd]; - half = bfpt.dwords[rd->settings_dword] >> rd->settings_shift; - spi_nor_set_read_settings_from_bfpt(read, half, rd->proto); - } - - /* - * Sector Erase settings. Reinitialize the uniform erase map using the - * Erase Types defined in the bfpt table. - */ - erase_mask = 0; - memset(&nor->erase_map, 0, sizeof(nor->erase_map)); - for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) { - const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i]; - u32 erasesize; - u8 opcode; - - half = bfpt.dwords[er->dword] >> er->shift; - erasesize = half & 0xff; - - /* erasesize == 0 means this Erase Type is not supported. */ - if (!erasesize) - continue; - - erasesize = 1U << erasesize; - opcode = (half >> 8) & 0xff; - erase_mask |= BIT(i); - spi_nor_set_erase_settings_from_bfpt(&erase_type[i], erasesize, - opcode, i); - } - spi_nor_init_uniform_erase_map(map, erase_mask, params->size); - /* - * Sort all the map's Erase Types in ascending order with the smallest - * erase size being the first member in the erase_type array. - */ - sort(erase_type, SNOR_ERASE_TYPE_MAX, sizeof(erase_type[0]), - spi_nor_map_cmp_erase_type, NULL); - /* - * Sort the erase types in the uniform region in order to update the - * uniform_erase_type bitmask. The bitmask will be used later on when - * selecting the uniform erase. - */ - spi_nor_regions_sort_erase_types(map); - map->uniform_erase_type = map->uniform_region.offset & - SNOR_ERASE_TYPE_MASK; - - /* Stop here if not JESD216 rev A or later. */ - if (bfpt_header->length < BFPT_DWORD_MAX) - return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, - params); - - /* Page size: this field specifies 'N' so the page size = 2^N bytes. */ - params->page_size = bfpt.dwords[BFPT_DWORD(11)]; - params->page_size &= BFPT_DWORD11_PAGE_SIZE_MASK; - params->page_size >>= BFPT_DWORD11_PAGE_SIZE_SHIFT; - params->page_size = 1U << params->page_size; - - /* Quad Enable Requirements. */ - switch (bfpt.dwords[BFPT_DWORD(15)] & BFPT_DWORD15_QER_MASK) { - case BFPT_DWORD15_QER_NONE: - params->quad_enable = no_quad_enable; - break; - - case BFPT_DWORD15_QER_SR2_BIT1_BUGGY: - case BFPT_DWORD15_QER_SR2_BIT1_NO_RD: - params->quad_enable = sr2_bit1_no_read_quad_enable; - break; - - case BFPT_DWORD15_QER_SR1_BIT6: - params->quad_enable = sr1_bit6_quad_enable; - break; - - case BFPT_DWORD15_QER_SR2_BIT7: - params->quad_enable = sr2_bit7_quad_enable; - break; - - case BFPT_DWORD15_QER_SR2_BIT1: - params->quad_enable = sr2_bit1_read_quad_enable; - break; - - default: - return -EINVAL; - } - - return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); -} - -#define SMPT_CMD_ADDRESS_LEN_MASK GENMASK(23, 22) -#define SMPT_CMD_ADDRESS_LEN_0 (0x0UL << 22) -#define SMPT_CMD_ADDRESS_LEN_3 (0x1UL << 22) -#define SMPT_CMD_ADDRESS_LEN_4 (0x2UL << 22) -#define SMPT_CMD_ADDRESS_LEN_USE_CURRENT (0x3UL << 22) - -#define SMPT_CMD_READ_DUMMY_MASK GENMASK(19, 16) -#define SMPT_CMD_READ_DUMMY_SHIFT 16 -#define SMPT_CMD_READ_DUMMY(_cmd) \ - (((_cmd) & SMPT_CMD_READ_DUMMY_MASK) >> SMPT_CMD_READ_DUMMY_SHIFT) -#define SMPT_CMD_READ_DUMMY_IS_VARIABLE 0xfUL - -#define SMPT_CMD_READ_DATA_MASK GENMASK(31, 24) -#define SMPT_CMD_READ_DATA_SHIFT 24 -#define SMPT_CMD_READ_DATA(_cmd) \ - (((_cmd) & SMPT_CMD_READ_DATA_MASK) >> SMPT_CMD_READ_DATA_SHIFT) - -#define SMPT_CMD_OPCODE_MASK GENMASK(15, 8) -#define SMPT_CMD_OPCODE_SHIFT 8 -#define SMPT_CMD_OPCODE(_cmd) \ - (((_cmd) & SMPT_CMD_OPCODE_MASK) >> SMPT_CMD_OPCODE_SHIFT) - -#define SMPT_MAP_REGION_COUNT_MASK GENMASK(23, 16) -#define SMPT_MAP_REGION_COUNT_SHIFT 16 -#define SMPT_MAP_REGION_COUNT(_header) \ - ((((_header) & SMPT_MAP_REGION_COUNT_MASK) >> \ - SMPT_MAP_REGION_COUNT_SHIFT) + 1) - -#define SMPT_MAP_ID_MASK GENMASK(15, 8) -#define SMPT_MAP_ID_SHIFT 8 -#define SMPT_MAP_ID(_header) \ - (((_header) & SMPT_MAP_ID_MASK) >> SMPT_MAP_ID_SHIFT) - -#define SMPT_MAP_REGION_SIZE_MASK GENMASK(31, 8) -#define SMPT_MAP_REGION_SIZE_SHIFT 8 -#define SMPT_MAP_REGION_SIZE(_region) \ - (((((_region) & SMPT_MAP_REGION_SIZE_MASK) >> \ - SMPT_MAP_REGION_SIZE_SHIFT) + 1) * 256) - -#define SMPT_MAP_REGION_ERASE_TYPE_MASK GENMASK(3, 0) -#define SMPT_MAP_REGION_ERASE_TYPE(_region) \ - ((_region) & SMPT_MAP_REGION_ERASE_TYPE_MASK) - -#define SMPT_DESC_TYPE_MAP BIT(1) -#define SMPT_DESC_END BIT(0) - -/** - * spi_nor_smpt_addr_width() - return the address width used in the - * configuration detection command. - * @nor: pointer to a 'struct spi_nor' - * @settings: configuration detection command descriptor, dword1 - */ -static u8 spi_nor_smpt_addr_width(const struct spi_nor *nor, const u32 settings) -{ - switch (settings & SMPT_CMD_ADDRESS_LEN_MASK) { - case SMPT_CMD_ADDRESS_LEN_0: - return 0; - case SMPT_CMD_ADDRESS_LEN_3: - return 3; - case SMPT_CMD_ADDRESS_LEN_4: - return 4; - case SMPT_CMD_ADDRESS_LEN_USE_CURRENT: - /* fall through */ - default: - return nor->addr_width; - } -} - -/** - * spi_nor_smpt_read_dummy() - return the configuration detection command read - * latency, in clock cycles. - * @nor: pointer to a 'struct spi_nor' - * @settings: configuration detection command descriptor, dword1 - * - * Return: the number of dummy cycles for an SMPT read - */ -static u8 spi_nor_smpt_read_dummy(const struct spi_nor *nor, const u32 settings) -{ - u8 read_dummy = SMPT_CMD_READ_DUMMY(settings); - - if (read_dummy == SMPT_CMD_READ_DUMMY_IS_VARIABLE) - return nor->read_dummy; - return read_dummy; -} - -/** - * spi_nor_get_map_in_use() - get the configuration map in use - * @nor: pointer to a 'struct spi_nor' - * @smpt: pointer to the sector map parameter table - */ -static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt) -{ - const u32 *ret = NULL; - u32 i, addr; - int err; - u8 addr_width, read_opcode, read_dummy; - u8 read_data_mask, data_byte, map_id; - - addr_width = nor->addr_width; - read_dummy = nor->read_dummy; - read_opcode = nor->read_opcode; - - map_id = 0; - i = 0; - /* Determine if there are any optional Detection Command Descriptors */ - while (!(smpt[i] & SMPT_DESC_TYPE_MAP)) { - read_data_mask = SMPT_CMD_READ_DATA(smpt[i]); - nor->addr_width = spi_nor_smpt_addr_width(nor, smpt[i]); - nor->read_dummy = spi_nor_smpt_read_dummy(nor, smpt[i]); - nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); - addr = smpt[i + 1]; - - err = spi_nor_read_raw(nor, addr, 1, &data_byte); - if (err) - goto out; - - /* - * Build an index value that is used to select the Sector Map - * Configuration that is currently in use. - */ - map_id = map_id << 1 | !!(data_byte & read_data_mask); - i = i + 2; - } - - /* Find the matching configuration map */ - while (SMPT_MAP_ID(smpt[i]) != map_id) { - if (smpt[i] & SMPT_DESC_END) - goto out; - /* increment the table index to the next map */ - i += SMPT_MAP_REGION_COUNT(smpt[i]) + 1; - } - - ret = smpt + i; - /* fall through */ -out: - nor->addr_width = addr_width; - nor->read_dummy = read_dummy; - nor->read_opcode = read_opcode; - return ret; -} - -/** - * spi_nor_region_check_overlay() - set overlay bit when the region is overlaid - * @region: pointer to a structure that describes a SPI NOR erase region - * @erase: pointer to a structure that describes a SPI NOR erase type - * @erase_type: erase type bitmask - */ -static void -spi_nor_region_check_overlay(struct spi_nor_erase_region *region, - const struct spi_nor_erase_type *erase, - const u8 erase_type) -{ - int i; - - for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { - if (!(erase_type & BIT(i))) - continue; - if (region->size & erase[i].size_mask) { - spi_nor_region_mark_overlay(region); - return; - } - } -} - -/** - * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map - * @nor: pointer to a 'struct spi_nor' - * @smpt: pointer to the sector map parameter table - * - * Return: 0 on success, -errno otherwise. - */ -static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, - const u32 *smpt) -{ - struct spi_nor_erase_map *map = &nor->erase_map; - const struct spi_nor_erase_type *erase = map->erase_type; - struct spi_nor_erase_region *region; - u64 offset; - u32 region_count; - int i, j; - u8 erase_type; - - region_count = SMPT_MAP_REGION_COUNT(*smpt); - /* - * The regions will be freed when the driver detaches from the - * device. - */ - region = devm_kcalloc(nor->dev, region_count, sizeof(*region), - GFP_KERNEL); - if (!region) - return -ENOMEM; - map->regions = region; - - map->uniform_erase_type = 0xff; - offset = 0; - /* Populate regions. */ - for (i = 0; i < region_count; i++) { - j = i + 1; /* index for the region dword */ - region[i].size = SMPT_MAP_REGION_SIZE(smpt[j]); - erase_type = SMPT_MAP_REGION_ERASE_TYPE(smpt[j]); - region[i].offset = offset | erase_type; - - spi_nor_region_check_overlay(®ion[i], erase, erase_type); - - /* - * Save the erase types that are supported in all regions and - * can erase the entire flash memory. - */ - map->uniform_erase_type &= erase_type; - - offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) + - region[i].size; - } - - spi_nor_region_mark_end(®ion[i - 1]); - - return 0; -} - -/** - * spi_nor_parse_smpt() - parse Sector Map Parameter Table - * @nor: pointer to a 'struct spi_nor' - * @smpt_header: sector map parameter table header - * - * This table is optional, but when available, we parse it to identify the - * location and size of sectors within the main data array of the flash memory - * device and to identify which Erase Types are supported by each sector. - * - * Return: 0 on success, -errno otherwise. - */ -static int spi_nor_parse_smpt(struct spi_nor *nor, - const struct sfdp_parameter_header *smpt_header) -{ - const u32 *sector_map; - u32 *smpt; - size_t len; - u32 addr; - int i, ret; - - /* Read the Sector Map Parameter Table. */ - len = smpt_header->length * sizeof(*smpt); - smpt = kmalloc(len, GFP_KERNEL); - if (!smpt) - return -ENOMEM; - - addr = SFDP_PARAM_HEADER_PTP(smpt_header); - ret = spi_nor_read_sfdp(nor, addr, len, smpt); - if (ret) - goto out; - - /* Fix endianness of the SMPT DWORDs. */ - for (i = 0; i < smpt_header->length; i++) - smpt[i] = le32_to_cpu(smpt[i]); - - sector_map = spi_nor_get_map_in_use(nor, smpt); - if (!sector_map) { - ret = -EINVAL; - goto out; - } - - ret = spi_nor_init_non_uniform_erase_map(nor, sector_map); - if (ret) - goto out; - - spi_nor_regions_sort_erase_types(&nor->erase_map); - /* fall through */ -out: - kfree(smpt); - return ret; -} - -/** - * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. - * @nor: pointer to a 'struct spi_nor' - * @params: pointer to the 'struct spi_nor_flash_parameter' to be - * filled - * - * The Serial Flash Discoverable Parameters are described by the JEDEC JESD216 - * specification. This is a standard which tends to supported by almost all - * (Q)SPI memory manufacturers. Those hard-coded tables allow us to learn at - * runtime the main parameters needed to perform basic SPI flash operations such - * as Fast Read, Page Program or Sector Erase commands. - * - * Return: 0 on success, -errno otherwise. - */ -static int spi_nor_parse_sfdp(struct spi_nor *nor, - struct spi_nor_flash_parameter *params) -{ - const struct sfdp_parameter_header *param_header, *bfpt_header; - struct sfdp_parameter_header *param_headers = NULL; - struct sfdp_header header; - struct device *dev = nor->dev; - size_t psize; - int i, err; - - /* Get the SFDP header. */ - err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(header), &header); - if (err < 0) - return err; - - /* Check the SFDP header version. */ - if (le32_to_cpu(header.signature) != SFDP_SIGNATURE || - header.major != SFDP_JESD216_MAJOR) - return -EINVAL; - - /* - * Verify that the first and only mandatory parameter header is a - * Basic Flash Parameter Table header as specified in JESD216. - */ - bfpt_header = &header.bfpt_header; - if (SFDP_PARAM_HEADER_ID(bfpt_header) != SFDP_BFPT_ID || - bfpt_header->major != SFDP_JESD216_MAJOR) - return -EINVAL; - - /* - * Allocate memory then read all parameter headers with a single - * Read SFDP command. These parameter headers will actually be parsed - * twice: a first time to get the latest revision of the basic flash - * parameter table, then a second time to handle the supported optional - * tables. - * Hence we read the parameter headers once for all to reduce the - * processing time. Also we use kmalloc() instead of devm_kmalloc() - * because we don't need to keep these parameter headers: the allocated - * memory is always released with kfree() before exiting this function. - */ - if (header.nph) { - psize = header.nph * sizeof(*param_headers); - - param_headers = kmalloc(psize, GFP_KERNEL); - if (!param_headers) - return -ENOMEM; - - err = spi_nor_read_sfdp(nor, sizeof(header), - psize, param_headers); - if (err < 0) { - dev_err(dev, "failed to read SFDP parameter headers\n"); - goto exit; - } - } - - /* - * Check other parameter headers to get the latest revision of - * the basic flash parameter table. - */ - for (i = 0; i < header.nph; i++) { - param_header = ¶m_headers[i]; - - if (SFDP_PARAM_HEADER_ID(param_header) == SFDP_BFPT_ID && - param_header->major == SFDP_JESD216_MAJOR && - (param_header->minor > bfpt_header->minor || - (param_header->minor == bfpt_header->minor && - param_header->length > bfpt_header->length))) - bfpt_header = param_header; - } - - err = spi_nor_parse_bfpt(nor, bfpt_header, params); - if (err) - goto exit; - - /* Parse other parameter headers. */ - for (i = 0; i < header.nph; i++) { - param_header = ¶m_headers[i]; - - switch (SFDP_PARAM_HEADER_ID(param_header)) { - case SFDP_SECTOR_MAP_ID: - err = spi_nor_parse_smpt(nor, param_header); - break; - - default: - break; - } - - if (err) - goto exit; - } - -exit: - kfree(param_headers); - return err; -} - static int spi_nor_init_params(struct spi_nor *nor, struct spi_nor_flash_parameter *params) { diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index 96b08b53f8f6..ae3eb40d7241 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -345,16 +345,31 @@ extern const struct spi_nor_manufacturer spi_nor_xmc; int en4_ex4_set_4byte(struct spi_nor *nor, bool enable); int en4_ex4_wen_set_4byte(struct spi_nor *nor, bool enable); int sr1_bit6_quad_enable(struct spi_nor *nor); +int sr2_bit7_quad_enable(struct spi_nor *nor); +int sr2_bit1_read_quad_enable(struct spi_nor *nor); +int sr2_bit1_no_read_quad_enable(struct spi_nor *nor); int no_quad_enable(struct spi_nor *nor); int write_enable(struct spi_nor *nor); int write_disable(struct spi_nor *nor); int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops); void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops); int spi_nor_wait_till_ready(struct spi_nor *nor); +void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, + u8 erase_mask, u64 flash_size); +void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size, + u8 opcode); +struct spi_nor_erase_region * +spi_nor_region_next(struct spi_nor_erase_region *region); +int spi_nor_read_raw(struct spi_nor *nor, u32 addr, size_t len, u8 *buf); +int spi_nor_hwcaps_read2cmd(u32 hwcaps); static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) { return mtd->priv; } +/* SFDP functions. */ +int spi_nor_parse_sfdp(struct spi_nor *nor, + struct spi_nor_flash_parameter *params); + #endif /* __LINUX_MTD_SPI_NOR_INTERNALS_H */ diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c new file mode 100644 index 000000000000..36343e3e6be0 --- /dev/null +++ b/drivers/mtd/spi-nor/sfdp.c @@ -0,0 +1,859 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005, Intec Automation Inc. + * Copyright (C) 2014, Freescale Semiconductor, Inc. + */ + +#include +#include +#include +#include + +#include "internals.h" + +/** + * spi_nor_read_sfdp() - read Serial Flash Discoverable Parameters. + * @nor: pointer to a 'struct spi_nor' + * @addr: offset in the SFDP area to start reading data from + * @len: number of bytes to read + * @buf: buffer where the SFDP data are copied into (dma-safe memory) + * + * Whatever the actual numbers of bytes for address and dummy cycles are + * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always + * followed by a 3-byte address and 8 dummy clock cycles. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr, + size_t len, void *buf) +{ + u8 addr_width, read_opcode, read_dummy; + int ret; + + read_opcode = nor->read_opcode; + addr_width = nor->addr_width; + read_dummy = nor->read_dummy; + + nor->read_opcode = SPINOR_OP_RDSFDP; + nor->addr_width = 3; + nor->read_dummy = 8; + + ret = spi_nor_read_raw(nor, addr, len, buf); + + nor->read_opcode = read_opcode; + nor->addr_width = addr_width; + nor->read_dummy = read_dummy; + + return ret; +} + +/** + * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters. + * @nor: pointer to a 'struct spi_nor' + * @addr: offset in the SFDP area to start reading data from + * @len: number of bytes to read + * @buf: buffer where the SFDP data are copied into + * + * Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not + * guaranteed to be dma-safe. + * + * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp() + * otherwise. + */ +static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr, + size_t len, void *buf) +{ + void *dma_safe_buf; + int ret; + + dma_safe_buf = kmalloc(len, GFP_KERNEL); + if (!dma_safe_buf) + return -ENOMEM; + + ret = spi_nor_read_sfdp(nor, addr, len, dma_safe_buf); + memcpy(buf, dma_safe_buf, len); + kfree(dma_safe_buf); + + return ret; +} + +/** + * spi_nor_set_erase_settings_from_bfpt() - set erase type settings from BFPT + * @erase: pointer to a structure that describes a SPI NOR erase type + * @size: the size of the sector/block erased by the erase type + * @opcode: the SPI command op code to erase the sector/block + * @i: erase type index as sorted in the Basic Flash Parameter Table + * + * The supported Erase Types will be sorted at init in ascending order, with + * the smallest Erase Type size being the first member in the erase_type array + * of the spi_nor_erase_map structure. Save the Erase Type index as sorted in + * the Basic Flash Parameter Table since it will be used later on to + * synchronize with the supported Erase Types defined in SFDP optional tables. + */ +static void +spi_nor_set_erase_settings_from_bfpt(struct spi_nor_erase_type *erase, + u32 size, u8 opcode, u8 i) +{ + erase->idx = i; + spi_nor_set_erase_type(erase, size, opcode); +} + +/** + * spi_nor_map_cmp_erase_type() - compare the map's erase types by size + * @l: member in the left half of the map's erase_type array + * @r: member in the right half of the map's erase_type array + * + * Comparison function used in the sort() call to sort in ascending order the + * map's erase types, the smallest erase type size being the first member in the + * sorted erase_type array. + * + * Return: the result of @l->size - @r->size + */ +static int spi_nor_map_cmp_erase_type(const void *l, const void *r) +{ + const struct spi_nor_erase_type *left = l, *right = r; + + return left->size - right->size; +} + +/** + * spi_nor_regions_sort_erase_types() - sort erase types in each region + * @map: the erase map of the SPI NOR + * + * Function assumes that the erase types defined in the erase map are already + * sorted in ascending order, with the smallest erase type size being the first + * member in the erase_type array. It replicates the sort done for the map's + * erase types. Each region's erase bitmask will indicate which erase types are + * supported from the sorted erase types defined in the erase map. + * Sort the all region's erase type at init in order to speed up the process of + * finding the best erase command at runtime. + */ +static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) +{ + struct spi_nor_erase_region *region = map->regions; + struct spi_nor_erase_type *erase_type = map->erase_type; + int i; + u8 region_erase_mask, sorted_erase_mask; + + while (region) { + region_erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; + + /* Replicate the sort done for the map's erase types. */ + sorted_erase_mask = 0; + for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) + if (erase_type[i].size && + region_erase_mask & BIT(erase_type[i].idx)) + sorted_erase_mask |= BIT(i); + + /* Overwrite erase mask. */ + region->offset = (region->offset & ~SNOR_ERASE_TYPE_MASK) | + sorted_erase_mask; + + region = spi_nor_region_next(region); + } +} + +#define SMPT_CMD_ADDRESS_LEN_MASK GENMASK(23, 22) +#define SMPT_CMD_ADDRESS_LEN_0 (0x0UL << 22) +#define SMPT_CMD_ADDRESS_LEN_3 (0x1UL << 22) +#define SMPT_CMD_ADDRESS_LEN_4 (0x2UL << 22) +#define SMPT_CMD_ADDRESS_LEN_USE_CURRENT (0x3UL << 22) + +#define SMPT_CMD_READ_DUMMY_MASK GENMASK(19, 16) +#define SMPT_CMD_READ_DUMMY_SHIFT 16 +#define SMPT_CMD_READ_DUMMY(_cmd) \ + (((_cmd) & SMPT_CMD_READ_DUMMY_MASK) >> SMPT_CMD_READ_DUMMY_SHIFT) +#define SMPT_CMD_READ_DUMMY_IS_VARIABLE 0xfUL + +#define SMPT_CMD_READ_DATA_MASK GENMASK(31, 24) +#define SMPT_CMD_READ_DATA_SHIFT 24 +#define SMPT_CMD_READ_DATA(_cmd) \ + (((_cmd) & SMPT_CMD_READ_DATA_MASK) >> SMPT_CMD_READ_DATA_SHIFT) + +#define SMPT_CMD_OPCODE_MASK GENMASK(15, 8) +#define SMPT_CMD_OPCODE_SHIFT 8 +#define SMPT_CMD_OPCODE(_cmd) \ + (((_cmd) & SMPT_CMD_OPCODE_MASK) >> SMPT_CMD_OPCODE_SHIFT) + +#define SMPT_MAP_REGION_COUNT_MASK GENMASK(23, 16) +#define SMPT_MAP_REGION_COUNT_SHIFT 16 +#define SMPT_MAP_REGION_COUNT(_header) \ + ((((_header) & SMPT_MAP_REGION_COUNT_MASK) >> \ + SMPT_MAP_REGION_COUNT_SHIFT) + 1) + +#define SMPT_MAP_ID_MASK GENMASK(15, 8) +#define SMPT_MAP_ID_SHIFT 8 +#define SMPT_MAP_ID(_header) \ + (((_header) & SMPT_MAP_ID_MASK) >> SMPT_MAP_ID_SHIFT) + +#define SMPT_MAP_REGION_SIZE_MASK GENMASK(31, 8) +#define SMPT_MAP_REGION_SIZE_SHIFT 8 +#define SMPT_MAP_REGION_SIZE(_region) \ + (((((_region) & SMPT_MAP_REGION_SIZE_MASK) >> \ + SMPT_MAP_REGION_SIZE_SHIFT) + 1) * 256) + +#define SMPT_MAP_REGION_ERASE_TYPE_MASK GENMASK(3, 0) +#define SMPT_MAP_REGION_ERASE_TYPE(_region) \ + ((_region) & SMPT_MAP_REGION_ERASE_TYPE_MASK) + +#define SMPT_DESC_TYPE_MAP BIT(1) +#define SMPT_DESC_END BIT(0) + +/** + * spi_nor_smpt_addr_width() - return the address width used in the + * configuration detection command. + * @nor: pointer to a 'struct spi_nor' + * @settings: configuration detection command descriptor, dword1 + */ +static u8 spi_nor_smpt_addr_width(const struct spi_nor *nor, const u32 settings) +{ + switch (settings & SMPT_CMD_ADDRESS_LEN_MASK) { + case SMPT_CMD_ADDRESS_LEN_0: + return 0; + case SMPT_CMD_ADDRESS_LEN_3: + return 3; + case SMPT_CMD_ADDRESS_LEN_4: + return 4; + case SMPT_CMD_ADDRESS_LEN_USE_CURRENT: + /* fall through */ + default: + return nor->addr_width; + } +} + +/** + * spi_nor_smpt_read_dummy() - return the configuration detection command read + * latency, in clock cycles. + * @nor: pointer to a 'struct spi_nor' + * @settings: configuration detection command descriptor, dword1 + * + * Return: the number of dummy cycles for an SMPT read + */ +static u8 spi_nor_smpt_read_dummy(const struct spi_nor *nor, const u32 settings) +{ + u8 read_dummy = SMPT_CMD_READ_DUMMY(settings); + + if (read_dummy == SMPT_CMD_READ_DUMMY_IS_VARIABLE) + return nor->read_dummy; + return read_dummy; +} + +/** + * spi_nor_get_map_in_use() - get the configuration map in use + * @nor: pointer to a 'struct spi_nor' + * @smpt: pointer to the sector map parameter table + */ +static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt) +{ + const u32 *ret = NULL; + u32 i, addr; + int err; + u8 addr_width, read_opcode, read_dummy; + u8 read_data_mask, data_byte, map_id; + + addr_width = nor->addr_width; + read_dummy = nor->read_dummy; + read_opcode = nor->read_opcode; + + map_id = 0; + i = 0; + /* Determine if there are any optional Detection Command Descriptors */ + while (!(smpt[i] & SMPT_DESC_TYPE_MAP)) { + read_data_mask = SMPT_CMD_READ_DATA(smpt[i]); + nor->addr_width = spi_nor_smpt_addr_width(nor, smpt[i]); + nor->read_dummy = spi_nor_smpt_read_dummy(nor, smpt[i]); + nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); + addr = smpt[i + 1]; + + err = spi_nor_read_raw(nor, addr, 1, &data_byte); + if (err) + goto out; + + /* + * Build an index value that is used to select the Sector Map + * Configuration that is currently in use. + */ + map_id = map_id << 1 | !!(data_byte & read_data_mask); + i = i + 2; + } + + /* Find the matching configuration map */ + while (SMPT_MAP_ID(smpt[i]) != map_id) { + if (smpt[i] & SMPT_DESC_END) + goto out; + /* increment the table index to the next map */ + i += SMPT_MAP_REGION_COUNT(smpt[i]) + 1; + } + + ret = smpt + i; + /* fall through */ +out: + nor->addr_width = addr_width; + nor->read_dummy = read_dummy; + nor->read_opcode = read_opcode; + return ret; +} + +/** + * spi_nor_region_check_overlay() - set overlay bit when the region is overlaid + * @region: pointer to a structure that describes a SPI NOR erase region + * @erase: pointer to a structure that describes a SPI NOR erase type + * @erase_type: erase type bitmask + */ +static void +spi_nor_region_check_overlay(struct spi_nor_erase_region *region, + const struct spi_nor_erase_type *erase, + const u8 erase_type) +{ + int i; + + for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { + if (!(erase_type & BIT(i))) + continue; + if (region->size & erase[i].size_mask) { + spi_nor_region_mark_overlay(region); + return; + } + } +} + +/** + * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map + * @nor: pointer to a 'struct spi_nor' + * @smpt: pointer to the sector map parameter table + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, + const u32 *smpt) +{ + struct spi_nor_erase_map *map = &nor->erase_map; + const struct spi_nor_erase_type *erase = map->erase_type; + struct spi_nor_erase_region *region; + u64 offset; + u32 region_count; + int i, j; + u8 erase_type; + + region_count = SMPT_MAP_REGION_COUNT(*smpt); + /* + * The regions will be freed when the driver detaches from the + * device. + */ + region = devm_kcalloc(nor->dev, region_count, sizeof(*region), + GFP_KERNEL); + if (!region) + return -ENOMEM; + map->regions = region; + + map->uniform_erase_type = 0xff; + offset = 0; + /* Populate regions. */ + for (i = 0; i < region_count; i++) { + j = i + 1; /* index for the region dword */ + region[i].size = SMPT_MAP_REGION_SIZE(smpt[j]); + erase_type = SMPT_MAP_REGION_ERASE_TYPE(smpt[j]); + region[i].offset = offset | erase_type; + + spi_nor_region_check_overlay(®ion[i], erase, erase_type); + + /* + * Save the erase types that are supported in all regions and + * can erase the entire flash memory. + */ + map->uniform_erase_type &= erase_type; + + offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) + + region[i].size; + } + + spi_nor_region_mark_end(®ion[i - 1]); + + return 0; +} + +/** + * spi_nor_parse_smpt() - parse Sector Map Parameter Table + * @nor: pointer to a 'struct spi_nor' + * @smpt_header: sector map parameter table header + * + * This table is optional, but when available, we parse it to identify the + * location and size of sectors within the main data array of the flash memory + * device and to identify which Erase Types are supported by each sector. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_parse_smpt(struct spi_nor *nor, + const struct sfdp_parameter_header *smpt_header) +{ + const u32 *sector_map; + u32 *smpt; + size_t len; + u32 addr; + int i, ret; + + /* Read the Sector Map Parameter Table. */ + len = smpt_header->length * sizeof(*smpt); + smpt = kmalloc(len, GFP_KERNEL); + if (!smpt) + return -ENOMEM; + + addr = SFDP_PARAM_HEADER_PTP(smpt_header); + ret = spi_nor_read_sfdp(nor, addr, len, smpt); + if (ret) + goto out; + + /* Fix endianness of the SMPT DWORDs. */ + for (i = 0; i < smpt_header->length; i++) + smpt[i] = le32_to_cpu(smpt[i]); + + sector_map = spi_nor_get_map_in_use(nor, smpt); + if (!sector_map) { + ret = -EINVAL; + goto out; + } + + ret = spi_nor_init_non_uniform_erase_map(nor, sector_map); + if (ret) + goto out; + + spi_nor_regions_sort_erase_types(&nor->erase_map); + /* fall through */ +out: + kfree(smpt); + return ret; +} + +static void +spi_nor_set_read_settings_from_bfpt(struct spi_nor_read_command *read, + u16 half, + enum spi_nor_protocol proto) +{ + read->num_mode_clocks = (half >> 5) & 0x07; + read->num_wait_states = (half >> 0) & 0x1f; + read->opcode = (half >> 8) & 0xff; + read->proto = proto; +} + +struct sfdp_bfpt_read { + /* The Fast Read x-y-z hardware capability in params->hwcaps.mask. */ + u32 hwcaps; + + /* + * The bit in BFPT DWORD tells us + * whether the Fast Read x-y-z command is supported. + */ + u32 supported_dword; + u32 supported_bit; + + /* + * The half-word at offset in BFPT DWORD + * encodes the op code, the number of mode clocks and the number of wait + * states to be used by Fast Read x-y-z command. + */ + u32 settings_dword; + u32 settings_shift; + + /* The SPI protocol for this Fast Read x-y-z command. */ + enum spi_nor_protocol proto; +}; + +static const struct sfdp_bfpt_read sfdp_bfpt_reads[] = { + /* Fast Read 1-1-2 */ + { + SNOR_HWCAPS_READ_1_1_2, + BFPT_DWORD(1), BIT(16), /* Supported bit */ + BFPT_DWORD(4), 0, /* Settings */ + SNOR_PROTO_1_1_2, + }, + + /* Fast Read 1-2-2 */ + { + SNOR_HWCAPS_READ_1_2_2, + BFPT_DWORD(1), BIT(20), /* Supported bit */ + BFPT_DWORD(4), 16, /* Settings */ + SNOR_PROTO_1_2_2, + }, + + /* Fast Read 2-2-2 */ + { + SNOR_HWCAPS_READ_2_2_2, + BFPT_DWORD(5), BIT(0), /* Supported bit */ + BFPT_DWORD(6), 16, /* Settings */ + SNOR_PROTO_2_2_2, + }, + + /* Fast Read 1-1-4 */ + { + SNOR_HWCAPS_READ_1_1_4, + BFPT_DWORD(1), BIT(22), /* Supported bit */ + BFPT_DWORD(3), 16, /* Settings */ + SNOR_PROTO_1_1_4, + }, + + /* Fast Read 1-4-4 */ + { + SNOR_HWCAPS_READ_1_4_4, + BFPT_DWORD(1), BIT(21), /* Supported bit */ + BFPT_DWORD(3), 0, /* Settings */ + SNOR_PROTO_1_4_4, + }, + + /* Fast Read 4-4-4 */ + { + SNOR_HWCAPS_READ_4_4_4, + BFPT_DWORD(5), BIT(4), /* Supported bit */ + BFPT_DWORD(7), 16, /* Settings */ + SNOR_PROTO_4_4_4, + }, +}; + +struct sfdp_bfpt_erase { + /* + * The half-word at offset in DWORD encodes the + * op code and erase sector size to be used by Sector Erase commands. + */ + u32 dword; + u32 shift; +}; + +static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { + /* Erase Type 1 in DWORD8 bits[15:0] */ + {BFPT_DWORD(8), 0}, + + /* Erase Type 2 in DWORD8 bits[31:16] */ + {BFPT_DWORD(8), 16}, + + /* Erase Type 3 in DWORD9 bits[15:0] */ + {BFPT_DWORD(9), 0}, + + /* Erase Type 4 in DWORD9 bits[31:16] */ + {BFPT_DWORD(9), 16}, +}; + +static int +spi_nor_post_bfpt_fixups(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) +{ + int ret; + + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->post_bfpt) { + ret = nor->manufacturer->fixups->post_bfpt(nor, bfpt_header, + bfpt, params); + if (ret) + return ret; + } + + if (nor->info->fixups && nor->info->fixups->post_bfpt) { + ret = nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, + params); + if (ret) + return ret; + } + + return 0; +} + +/** + * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. + * @nor: pointer to a 'struct spi_nor' + * @bfpt_header: pointer to the 'struct sfdp_parameter_header' describing + * the Basic Flash Parameter Table length and version + * @params: pointer to the 'struct spi_nor_flash_parameter' to be + * filled + * + * The Basic Flash Parameter Table is the main and only mandatory table as + * defined by the SFDP (JESD216) specification. + * It provides us with the total size (memory density) of the data array and + * the number of address bytes for Fast Read, Page Program and Sector Erase + * commands. + * For Fast READ commands, it also gives the number of mode clock cycles and + * wait states (regrouped in the number of dummy clock cycles) for each + * supported instruction op code. + * For Page Program, the page size is now available since JESD216 rev A, however + * the supported instruction op codes are still not provided. + * For Sector Erase commands, this table stores the supported instruction op + * codes and the associated sector sizes. + * Finally, the Quad Enable Requirements (QER) are also available since JESD216 + * rev A. The QER bits encode the manufacturer dependent procedure to be + * executed to set the Quad Enable (QE) bit in some internal register of the + * Quad SPI memory. Indeed the QE bit, when it exists, must be set before + * sending any Quad SPI command to the memory. Actually, setting the QE bit + * tells the memory to reassign its WP# and HOLD#/RESET# pins to functions IO2 + * and IO3 hence enabling 4 (Quad) I/O lines. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_parse_bfpt(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + struct spi_nor_flash_parameter *params) +{ + struct spi_nor_erase_map *map = &nor->erase_map; + struct spi_nor_erase_type *erase_type = map->erase_type; + struct sfdp_bfpt bfpt; + size_t len; + int i, cmd, err; + u32 addr; + u16 half; + u8 erase_mask; + + /* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs. */ + if (bfpt_header->length < BFPT_DWORD_MAX_JESD216) + return -EINVAL; + + /* Read the Basic Flash Parameter Table. */ + len = min_t(size_t, sizeof(bfpt), + bfpt_header->length * sizeof(u32)); + addr = SFDP_PARAM_HEADER_PTP(bfpt_header); + memset(&bfpt, 0, sizeof(bfpt)); + err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt); + if (err < 0) + return err; + + /* Fix endianness of the BFPT DWORDs. */ + for (i = 0; i < BFPT_DWORD_MAX; i++) + bfpt.dwords[i] = le32_to_cpu(bfpt.dwords[i]); + + /* Number of address bytes. */ + switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) { + case BFPT_DWORD1_ADDRESS_BYTES_3_ONLY: + nor->addr_width = 3; + break; + + case BFPT_DWORD1_ADDRESS_BYTES_4_ONLY: + nor->addr_width = 4; + break; + + default: + break; + } + + /* Flash Memory Density (in bits). */ + params->size = bfpt.dwords[BFPT_DWORD(2)]; + if (params->size & BIT(31)) { + params->size &= ~BIT(31); + + /* + * Prevent overflows on params->size. Anyway, a NOR of 2^64 + * bits is unlikely to exist so this error probably means + * the BFPT we are reading is corrupted/wrong. + */ + if (params->size > 63) + return -EINVAL; + + params->size = 1ULL << params->size; + } else { + params->size++; + } + params->size >>= 3; /* Convert to bytes. */ + + /* Fast Read settings. */ + for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_reads); i++) { + const struct sfdp_bfpt_read *rd = &sfdp_bfpt_reads[i]; + struct spi_nor_read_command *read; + + if (!(bfpt.dwords[rd->supported_dword] & rd->supported_bit)) { + params->hwcaps.mask &= ~rd->hwcaps; + continue; + } + + params->hwcaps.mask |= rd->hwcaps; + cmd = spi_nor_hwcaps_read2cmd(rd->hwcaps); + read = ¶ms->reads[cmd]; + half = bfpt.dwords[rd->settings_dword] >> rd->settings_shift; + spi_nor_set_read_settings_from_bfpt(read, half, rd->proto); + } + + /* + * Sector Erase settings. Reinitialize the uniform erase map using the + * Erase Types defined in the bfpt table. + */ + erase_mask = 0; + memset(&nor->erase_map, 0, sizeof(nor->erase_map)); + for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) { + const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i]; + u32 erasesize; + u8 opcode; + + half = bfpt.dwords[er->dword] >> er->shift; + erasesize = half & 0xff; + + /* erasesize == 0 means this Erase Type is not supported. */ + if (!erasesize) + continue; + + erasesize = 1U << erasesize; + opcode = (half >> 8) & 0xff; + erase_mask |= BIT(i); + spi_nor_set_erase_settings_from_bfpt(&erase_type[i], erasesize, + opcode, i); + } + spi_nor_init_uniform_erase_map(map, erase_mask, params->size); + /* + * Sort all the map's Erase Types in ascending order with the smallest + * erase size being the first member in the erase_type array. + */ + sort(erase_type, SNOR_ERASE_TYPE_MAX, sizeof(erase_type[0]), + spi_nor_map_cmp_erase_type, NULL); + /* + * Sort the erase types in the uniform region in order to update the + * uniform_erase_type bitmask. The bitmask will be used later on when + * selecting the uniform erase. + */ + spi_nor_regions_sort_erase_types(map); + map->uniform_erase_type = map->uniform_region.offset & + SNOR_ERASE_TYPE_MASK; + + /* Stop here if not JESD216 rev A or later. */ + if (bfpt_header->length < BFPT_DWORD_MAX) + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, + params); + + /* Page size: this field specifies 'N' so the page size = 2^N bytes. */ + params->page_size = bfpt.dwords[BFPT_DWORD(11)]; + params->page_size &= BFPT_DWORD11_PAGE_SIZE_MASK; + params->page_size >>= BFPT_DWORD11_PAGE_SIZE_SHIFT; + params->page_size = 1U << params->page_size; + + /* Quad Enable Requirements. */ + switch (bfpt.dwords[BFPT_DWORD(15)] & BFPT_DWORD15_QER_MASK) { + case BFPT_DWORD15_QER_NONE: + params->quad_enable = no_quad_enable; + break; + + case BFPT_DWORD15_QER_SR2_BIT1_BUGGY: + case BFPT_DWORD15_QER_SR2_BIT1_NO_RD: + params->quad_enable = sr2_bit1_no_read_quad_enable; + break; + + case BFPT_DWORD15_QER_SR1_BIT6: + params->quad_enable = sr1_bit6_quad_enable; + break; + + case BFPT_DWORD15_QER_SR2_BIT7: + params->quad_enable = sr2_bit7_quad_enable; + break; + + case BFPT_DWORD15_QER_SR2_BIT1: + params->quad_enable = sr2_bit1_read_quad_enable; + break; + + default: + return -EINVAL; + } + + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); +} + +/** + * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. + * @nor: pointer to a 'struct spi_nor' + * @params: pointer to the 'struct spi_nor_flash_parameter' to be + * filled + * + * The Serial Flash Discoverable Parameters are described by the JEDEC JESD216 + * specification. This is a standard which tends to supported by almost all + * (Q)SPI memory manufacturers. Those hard-coded tables allow us to learn at + * runtime the main parameters needed to perform basic SPI flash operations such + * as Fast Read, Page Program or Sector Erase commands. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_parse_sfdp(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + const struct sfdp_parameter_header *param_header, *bfpt_header; + struct sfdp_parameter_header *param_headers = NULL; + struct sfdp_header header; + struct device *dev = nor->dev; + size_t psize; + int i, err; + + /* Get the SFDP header. */ + err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(header), &header); + if (err < 0) + return err; + + /* Check the SFDP header version. */ + if (le32_to_cpu(header.signature) != SFDP_SIGNATURE || + header.major != SFDP_JESD216_MAJOR) + return -EINVAL; + + /* + * Verify that the first and only mandatory parameter header is a + * Basic Flash Parameter Table header as specified in JESD216. + */ + bfpt_header = &header.bfpt_header; + if (SFDP_PARAM_HEADER_ID(bfpt_header) != SFDP_BFPT_ID || + bfpt_header->major != SFDP_JESD216_MAJOR) + return -EINVAL; + + /* + * Allocate memory then read all parameter headers with a single + * Read SFDP command. These parameter headers will actually be parsed + * twice: a first time to get the latest revision of the basic flash + * parameter table, then a second time to handle the supported optional + * tables. + * Hence we read the parameter headers once for all to reduce the + * processing time. Also we use kmalloc() instead of devm_kmalloc() + * because we don't need to keep these parameter headers: the allocated + * memory is always released with kfree() before exiting this function. + */ + if (header.nph) { + psize = header.nph * sizeof(*param_headers); + + param_headers = kmalloc(psize, GFP_KERNEL); + if (!param_headers) + return -ENOMEM; + + err = spi_nor_read_sfdp(nor, sizeof(header), + psize, param_headers); + if (err < 0) { + dev_err(dev, "failed to read SFDP parameter headers\n"); + goto exit; + } + } + + /* + * Check other parameter headers to get the latest revision of + * the basic flash parameter table. + */ + for (i = 0; i < header.nph; i++) { + param_header = ¶m_headers[i]; + + if (SFDP_PARAM_HEADER_ID(param_header) == SFDP_BFPT_ID && + param_header->major == SFDP_JESD216_MAJOR && + (param_header->minor > bfpt_header->minor || + (param_header->minor == bfpt_header->minor && + param_header->length > bfpt_header->length))) + bfpt_header = param_header; + } + + err = spi_nor_parse_bfpt(nor, bfpt_header, params); + if (err) + goto exit; + + /* Parse other parameter headers. */ + for (i = 0; i < header.nph; i++) { + param_header = ¶m_headers[i]; + + switch (SFDP_PARAM_HEADER_ID(param_header)) { + case SFDP_SECTOR_MAP_ID: + err = spi_nor_parse_smpt(nor, param_header); + break; + + default: + break; + } + + if (err) + goto exit; + } + +exit: + kfree(param_headers); + return err; +} From patchwork Fri Dec 7 09:26:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009285 X-Patchwork-Delegate: tudor.ambarus@gmail.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="IzdXNbB8"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="0pjZpWA1"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::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 43B6hP30Clz9s3q for ; Fri, 7 Dec 2018 20:32:53 +1100 (AEDT) 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=VoVZr2kReQgxLGN367jYSS51ZBP3pium0xdyFZgBw/4=; b=IzdXNbB8jpQaxKGVR0FiX1jg+G 77vT3EPy7rJcOmd6T0jQJT2x6OerfYvvSZ9vgbwlsW5t4bktosxeiyBAYsy6gfWZ232gZ3Tz2h2HP JFMZtolmHXOUPPG1byL63ZluKtGqwQ1og4XoD3S1TIR+LoI94UZGH6bVrI98IdPbuKEZVbPhk5b9I an0SCjkTQDZONA3MqlB7lErce8s9vR80Afaef6FmEhvmcbp2++lBBvfKq4yQ3COx/Ci78rcqwUnYu JwYywDV1hJMFxi0hh8Yzjp5Ejf5gbfgMD/zkSgM1jYjo+hxEj1DqFYtN4GAWna++eL84gx+0Jps1c 5JgQznAg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCV6-0007wt-Hk; Fri, 07 Dec 2018 09:32:48 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ8-0001my-Qt for linux-mtd@bombadil.infradead.org; Fri, 07 Dec 2018 09:27:40 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=70dvIM+5diSGdEaEzG1okPy4LWlzqSYTZpFjkHNXXlg=; b=0pjZpWA1MhkG4jShHCr8F5AKz DrgQu7ldCIKkzbgndFtOVjCsZKwVKHW/AvUNeBYYEZJYRBDmU1Wl6wKR3iawnwguzar9359idUxei 256N95I0fFzsSnGOhjlVzITGoDz2ZQdeu+sDkJ77MqpFYSprjPszjO1M9sVpr8twHP+Ex26bw6RxM iOnO7jD2BSE9VLy9YR7DxK2EbmZFh4y8y4RUiCp3K+rE+FPDcCfIvdkLD7Lek+GB99qkCDd7IYe0Z CGZJWOMscYEyoFmnjTGMDLQmp+sSPqkTCpEiuHWtY+iT1vI1Cc2necKMmF3C2O+tiTLC0glP0LhCY nfVh+FFig==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCQ4-0005hX-Vn for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:38 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 4136C20E2C; Fri, 7 Dec 2018 10:27:08 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.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.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 133A220E31; Fri, 7 Dec 2018 10:26:45 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 34/34] mtd: spi-nor: Add sfdp fixups hooks Date: Fri, 7 Dec 2018 10:26:37 +0100 Message-Id: <20181207092637.18687-35-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_042737_300248_18030F5A X-CRM114-Status: GOOD ( 15.70 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on merlin.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 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: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Experience has proven that SFDP tables are sometimes wrong, and the parsing that is done by the core can lead ton erroneous flash config which can sometimes be harmful. This leaves us 2 options: 1/ set the SPI_NOR_SKIP_SFDP flag and completely ignore SFDP parsing 2/ fix SFDP tables at runtime While #1 should always work, it might implies extra work if most of the SFDP is correct. #2 has the benefit of keeping the generic SFDP parsing logic almost untouched while allowing SPI NOR manufacturer drivers to fix the broken bits. Add three new hooks to do that. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/internals.h | 7 ++++ drivers/mtd/spi-nor/sfdp.c | 57 +++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/internals.h b/drivers/mtd/spi-nor/internals.h index ae3eb40d7241..da71145995d9 100644 --- a/drivers/mtd/spi-nor/internals.h +++ b/drivers/mtd/spi-nor/internals.h @@ -188,6 +188,8 @@ struct sfdp_bfpt { /** * struct spi_nor_fixups - SPI NOR fixup hooks + * @sfdp_hdr: SFDP header fixups + * @sfdp_hdr: SFDP parameter headers fixups * @post_bfpt: called after the BFPT table has been parsed * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs * that do not support RDSFDP). Typically used to tweak various @@ -199,6 +201,11 @@ struct sfdp_bfpt { * table is broken or not available. */ struct spi_nor_fixups { + int (*sfdp_hdr)(struct spi_nor *nor, + struct sfdp_header *hdr); + int (*sfdp_param_hdrs)(struct spi_nor *nor, + struct sfdp_header *hdr, + struct sfdp_parameter_header *param_hdrs); int (*post_bfpt)(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt, diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 36343e3e6be0..a8cd070e4ea2 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -534,8 +534,8 @@ static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { static int spi_nor_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) { int ret; @@ -748,6 +748,50 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); } +static int spi_nor_sfdp_hdr_fixups(struct spi_nor *nor, + struct sfdp_header *hdr) +{ + int ret; + + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->sfdp_hdr) { + ret = nor->manufacturer->fixups->sfdp_hdr(nor, hdr); + if (ret) + return ret; + } + + if (nor->info->fixups && nor->info->fixups->sfdp_hdr) { + ret = nor->info->fixups->sfdp_hdr(nor, hdr); + if (ret) + return ret; + } + + return 0; +} + +static int +spi_nor_sfdp_param_hdrs_fixups(struct spi_nor *nor, struct sfdp_header *hdr, + struct sfdp_parameter_header *param_hdrs) +{ + int ret; + + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->sfdp_param_hdrs) { + ret = nor->manufacturer->fixups->sfdp_param_hdrs(nor, hdr, + param_hdrs); + if (ret) + return ret; + } + + if (nor->info->fixups && nor->info->fixups->sfdp_hdr) { + ret = nor->info->fixups->sfdp_param_hdrs(nor, hdr, param_hdrs); + if (ret) + return ret; + } + + return 0; +} + /** * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. * @nor: pointer to a 'struct spi_nor' @@ -777,6 +821,10 @@ int spi_nor_parse_sfdp(struct spi_nor *nor, if (err < 0) return err; + err = spi_nor_sfdp_hdr_fixups(nor, &header); + if (err) + return err; + /* Check the SFDP header version. */ if (le32_to_cpu(header.signature) != SFDP_SIGNATURE || header.major != SFDP_JESD216_MAJOR) @@ -815,6 +863,11 @@ int spi_nor_parse_sfdp(struct spi_nor *nor, dev_err(dev, "failed to read SFDP parameter headers\n"); goto exit; } + + err = spi_nor_sfdp_param_hdrs_fixups(nor, &header, + param_headers); + if (err) + return err; } /*