From nobody Thu Jun 18 23:53:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E664C433EF for ; Mon, 11 Apr 2022 12:54:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346267AbiDKM4O (ORCPT ); Mon, 11 Apr 2022 08:56:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346251AbiDKM4I (ORCPT ); Mon, 11 Apr 2022 08:56:08 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B019338AD for ; Mon, 11 Apr 2022 05:53:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1649681634; x=1681217634; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YxGwEXdiW2HWJutHcMnKMQvWB9GLiCYZWJLMxk1Flq0=; b=rDTNCJzCUnDQzBoiKUsj8WlxIRCzR43EXWpHtsSjCEfnPC+8tKCMj4U3 DVhrGF1bzrZy+05eIcS8+VRYeQ2C9CkUPbUCZna5GdTcDfknrlGKCMGPQ Bssx+6wRUAtIdECpMknJNXew2ftDwaZldm4bYuW5A53THgeBK2DuR2P6Q 6IuokJaVi7BuJDHAtjdJcGqm5LDn031490SRPG6owGoL1lxfxOckWxRZ7 PPchsQ+hpsMxzCIQmmq9xpPoNF0LvdGYdgud4QlHiQJXkyo0O03SIbBLM TzpOfDQFDGNcrmnqed+YJpMryC1shP5kBrNAgiV5vBZmSCgJKAWT1b6F8 Q==; X-IronPort-AV: E=Sophos;i="5.90,251,1643698800"; d="scan'208";a="169171556" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Apr 2022 05:53:53 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 11 Apr 2022 05:53:53 -0700 Received: from ROB-ULT-M18064N.mchp-main.com (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 11 Apr 2022 05:53:51 -0700 From: Tudor Ambarus To: , CC: , , , , , , Tudor Ambarus Subject: [PATCH v3 1/3] mtd: spi-nor: Parse BFPT to determine the 4-Byte Address Mode methods Date: Mon, 11 Apr 2022 15:53:44 +0300 Message-ID: <20220411125346.118274-2-tudor.ambarus@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220411125346.118274-1-tudor.ambarus@microchip.com> References: <20220411125346.118274-1-tudor.ambarus@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" BFPT[DWORD(16)] defines the methods to enter and exit the 4-Byte Address Mode. Parse BFPT to determine the method. Will rename the methods with generic names in a further patch, to keep things trackable in this one. Some regressions may be introduced by this patch, because the params->set_4byte_addr_mode method that was set either in spi_nor_init_default_params() or later overwritten in default_init() hooks, may now be overwritten with a different value based on the BFPT data. If that's the case, the fix is to introduce a post_bfpt fixup hook where one should fix the wrong BFPT info. Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav --- v3: move BFPT definitions in sfdp.h as they may be used by manufacturer drivers to handle flash ID collisions. drivers/mtd/spi-nor/core.c | 63 ------------------- drivers/mtd/spi-nor/core.h | 1 - drivers/mtd/spi-nor/micron-st.c | 24 -------- drivers/mtd/spi-nor/sfdp.c | 105 ++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/sfdp.h | 29 +++++++++ drivers/mtd/spi-nor/winbond.c | 16 +++-- 6 files changed, 144 insertions(+), 94 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index fe853532204c..2b26a8cef0c3 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -502,69 +502,6 @@ int spi_nor_read_cr(struct spi_nor *nor, u8 *cr) return ret; } =20 -/** - * spi_nor_set_4byte_addr_mode() - Enter/Exit 4-byte address mode. - * @nor: pointer to 'struct spi_nor'. - * @enable: true to enter the 4-byte address mode, false to exit the 4-byte - * address mode. - * - * Return: 0 on success, -errno otherwise. - */ -int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) -{ - int ret; - - if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_EN4B_EX4B_OP(enable); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret =3D spi_mem_exec_op(nor->spimem, &op); - } else { - ret =3D spi_nor_controller_ops_write_reg(nor, - enable ? SPINOR_OP_EN4B : - SPINOR_OP_EX4B, - NULL, 0); - } - - if (ret) - dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); - - return ret; -} - -/** - * spansion_set_4byte_addr_mode() - Set 4-byte address mode for Spansion - * flashes. - * @nor: pointer to 'struct spi_nor'. - * @enable: true to enter the 4-byte address mode, false to exit the 4-byte - * address mode. - * - * Return: 0 on success, -errno otherwise. - */ -static int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable) -{ - int ret; - - nor->bouncebuf[0] =3D enable << 7; - - if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_BRWR_OP(nor->bouncebuf); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret =3D spi_mem_exec_op(nor->spimem, &op); - } else { - ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_BRWR, - nor->bouncebuf, 1); - } - - if (ret) - dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); - - return ret; -} - /** * spi_nor_write_ear() - Write Extended Address Register. * @nor: pointer to 'struct spi_nor'. diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 8b7e597fd38c..c83d5e75c563 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -634,7 +634,6 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor, const enum spi_nor_protocol proto); int spi_nor_write_enable(struct spi_nor *nor); int spi_nor_write_disable(struct spi_nor *nor); -int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); int spi_nor_write_ear(struct spi_nor *nor, u8 ear); int spi_nor_wait_till_ready(struct spi_nor *nor); int spi_nor_global_block_unlock(struct spi_nor *nor); diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-s= t.c index 26b9a1c2309d..d2903c5b5b87 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -298,30 +298,6 @@ static const struct flash_info st_nor_parts[] =3D { { "m25px80", INFO(0x207114, 0, 64 * 1024, 16) }, }; =20 -/** - * micron_st_nor_set_4byte_addr_mode() - Set 4-byte address mode for ST and - * Micron flashes. - * @nor: pointer to 'struct spi_nor'. - * @enable: true to enter the 4-byte address mode, false to exit the 4-byte - * address mode. - * - * Return: 0 on success, -errno otherwise. - */ -static int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool ena= ble) -{ - int ret; - - ret =3D spi_nor_write_enable(nor); - if (ret) - return ret; - - ret =3D spi_nor_set_4byte_addr_mode(nor, enable); - if (ret) - return ret; - - return spi_nor_write_disable(nor); -} - /** * micron_st_nor_read_fsr() - Read the Flag Status Register. * @nor: pointer to 'struct spi_nor' diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index a5211543d30d..2e40eba3744d 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -401,6 +401,93 @@ static void spi_nor_regions_sort_erase_types(struct sp= i_nor_erase_map *map) } } =20 +/** + * spansion_set_4byte_addr_mode() - Set 4-byte address mode for Spansion + * flashes. + * @nor: pointer to 'struct spi_nor'. + * @enable: true to enter the 4-byte address mode, false to exit the 4-byte + * address mode. + * + * Return: 0 on success, -errno otherwise. + */ +int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +{ + int ret; + + nor->bouncebuf[0] =3D enable << 7; + + if (nor->spimem) { + struct spi_mem_op op =3D SPI_NOR_BRWR_OP(nor->bouncebuf); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret =3D spi_mem_exec_op(nor->spimem, &op); + } else { + ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_BRWR, + nor->bouncebuf, 1); + } + + if (ret) + dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); + + return ret; +} + +/** + * spi_nor_set_4byte_addr_mode() - Enter/Exit 4-byte address mode. + * @nor: pointer to 'struct spi_nor'. + * @enable: true to enter the 4-byte address mode, false to exit the 4-byte + * address mode. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op =3D SPI_NOR_EN4B_EX4B_OP(enable); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret =3D spi_mem_exec_op(nor->spimem, &op); + } else { + ret =3D spi_nor_controller_ops_write_reg(nor, + enable ? SPINOR_OP_EN4B : + SPINOR_OP_EX4B, + NULL, 0); + } + + if (ret) + dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); + + return ret; +} + +/** + * micron_st_nor_set_4byte_addr_mode() - Set 4-byte address mode for ST and + * Micron flashes. + * @nor: pointer to 'struct spi_nor'. + * @enable: true to enter the 4-byte address mode, false to exit the 4-byte + * address mode. + * + * Return: 0 on success, -errno otherwise. + */ +int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +{ + int ret; + + ret =3D spi_nor_write_enable(nor); + if (ret) + return ret; + + ret =3D spi_nor_set_4byte_addr_mode(nor, enable); + if (ret) + return ret; + + return spi_nor_write_disable(nor); +} + /** * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. * @nor: pointer to a 'struct spi_nor' @@ -606,6 +693,24 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, break; } =20 + switch (bfpt.dwords[BFPT_DWORD(16)] & BFPT_DWORD16_4B_ADDR_MODE_MASK) { + case BFPT_DWORD16_4B_ADDR_MODE_BRWR: + params->set_4byte_addr_mode =3D spansion_set_4byte_addr_mode; + break; + + case BFPT_DWORD16_4B_ADDR_MODE_WREN_EN4B_EX4B: + params->set_4byte_addr_mode =3D micron_st_nor_set_4byte_addr_mode; + break; + + case BFPT_DWORD16_4B_ADDR_MODE_EN4B_EX4B: + params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode; + break; + + default: + dev_dbg(nor->dev, "BFPT: 4-Byte Address Mode method is not recognized or= not implemented\n"); + break; + } + /* Soft Reset support. */ if (bfpt.dwords[BFPT_DWORD(16)] & BFPT_DWORD16_SWRST_EN_RST) nor->flags |=3D SNOR_F_SOFT_RESET; diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h index bbf80d2990ab..3a3744da78ba 100644 --- a/drivers/mtd/spi-nor/sfdp.h +++ b/drivers/mtd/spi-nor/sfdp.h @@ -90,6 +90,32 @@ struct sfdp_bfpt { #define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) #define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ =20 +#define BFPT_DWORD16_EN4B_MASK GENMASK(31, 24) +#define BFPT_DWORD16_EN4B_ALWAYS_4B BIT(30) +#define BFPT_DWORD16_EN4B_4B_OPCODES BIT(29) +#define BFPT_DWORD16_EN4B_16BIT_NV_CR BIT(28) +#define BFPT_DWORD16_EN4B_BRWR BIT(27) +#define BFPT_DWORD16_EN4B_WREAR BIT(26) +#define BFPT_DWORD16_EN4B_WREN_EN4B BIT(25) +#define BFPT_DWORD16_EN4B_EN4B BIT(24) +#define BFPT_DWORD16_EX4B_MASK GENMASK(18, 14) +#define BFPT_DWORD16_EX4B_16BIT_NV_CR BIT(18) +#define BFPT_DWORD16_EX4B_BRWR BIT(17) +#define BFPT_DWORD16_EX4B_WREAR BIT(16) +#define BFPT_DWORD16_EX4B_WREN_EX4B BIT(15) +#define BFPT_DWORD16_EX4B_EX4B BIT(14) +#define BFPT_DWORD16_4B_ADDR_MODE_MASK \ + (BFPT_DWORD16_EN4B_MASK | BFPT_DWORD16_EX4B_MASK) +#define BFPT_DWORD16_4B_ADDR_MODE_16BIT_NV_CR \ + (BFPT_DWORD16_EN4B_16BIT_NV_CR | BFPT_DWORD16_EX4B_16BIT_NV_CR) +#define BFPT_DWORD16_4B_ADDR_MODE_BRWR \ + (BFPT_DWORD16_EN4B_BRWR | BFPT_DWORD16_EX4B_BRWR) +#define BFPT_DWORD16_4B_ADDR_MODE_WREAR \ + (BFPT_DWORD16_EN4B_WREAR | BFPT_DWORD16_EX4B_WREAR) +#define BFPT_DWORD16_4B_ADDR_MODE_WREN_EN4B_EX4B \ + (BFPT_DWORD16_EN4B_WREN_EN4B | BFPT_DWORD16_EX4B_WREN_EX4B) +#define BFPT_DWORD16_4B_ADDR_MODE_EN4B_EX4B \ + (BFPT_DWORD16_EN4B_EN4B | BFPT_DWORD16_EX4B_EX4B) #define BFPT_DWORD16_SWRST_EN_RST BIT(12) =20 #define BFPT_DWORD18_CMD_EXT_MASK GENMASK(30, 29) @@ -107,6 +133,9 @@ struct sfdp_parameter_header { u8 id_msb; }; =20 +int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable); +int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); +int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); int spi_nor_parse_sfdp(struct spi_nor *nor); =20 #endif /* __LINUX_MTD_SFDP_H */ diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index fe80dffc2e70..374ba82bff49 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -170,19 +170,23 @@ static const struct spi_nor_otp_ops winbond_nor_otp_o= ps =3D { .is_locked =3D spi_nor_otp_is_locked_sr2, }; =20 -static void winbond_nor_default_init(struct spi_nor *nor) -{ - nor->params->set_4byte_addr_mode =3D winbond_nor_set_4byte_addr_mode; -} - static void winbond_nor_late_init(struct spi_nor *nor) { if (nor->params->otp.org->n_regions) nor->params->otp.ops =3D &winbond_nor_otp_ops; + + /* + * Winbond seems to require that the Extended Address Register to be set + * to zero when exiting the 4-Byte Address Mode, at least for W25Q256FV. + * This requirement is not described in the JESD216 SFDP standard, thus + * it is Winbond specific. Since we do not know if other Winbond flashes + * have the same requirement, play safe and overwrite the method parsed + * from BFPT, if any. + */ + nor->params->set_4byte_addr_mode =3D winbond_nor_set_4byte_addr_mode; } =20 static const struct spi_nor_fixups winbond_nor_fixups =3D { - .default_init =3D winbond_nor_default_init, .late_init =3D winbond_nor_late_init, }; =20 --=20 2.25.1 From nobody Thu Jun 18 23:53:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4B9DC433F5 for ; Mon, 11 Apr 2022 12:54:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346284AbiDKM4R (ORCPT ); Mon, 11 Apr 2022 08:56:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346257AbiDKM4L (ORCPT ); Mon, 11 Apr 2022 08:56:11 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CB0F3DA5C for ; Mon, 11 Apr 2022 05:53:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1649681638; x=1681217638; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=06+0IGi/qVCaEzVy2orxTRzRoyFh8SISzaLVMzQyQHQ=; b=NywRFozrZLaeBjnxQz/QgoyceoD8S8/tfgwQxP9VBXdexy869DoroM+t IdIPgov/LOtkqzACTZDTuOyod+D0nPCMHfQ+ByuKx/B4CRiVEB0ILvGsx LjPtnuHJHRSufHWexUraYFTtbWo7ZWIC4D/sx+u2SNb59xvbdpRJzPNeK GP7tq9HTE6dyRtQgD/Bg35QSkyh43NNDbX8/1vteDaXoKzC+oo01objaT M6pf5IMafSuOQ9aYzjg0+0Vi9odK0kSKgwg5ySmP7+V8DSzIqfsvrsmmy ewtLKvi1cOzxdMl3zJdsdCrA6AlhVNmWM87Yf4OSFtYucUnlRZhCCo0K8 Q==; X-IronPort-AV: E=Sophos;i="5.90,251,1643698800"; d="scan'208";a="152228217" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Apr 2022 05:53:57 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 11 Apr 2022 05:53:56 -0700 Received: from ROB-ULT-M18064N.mchp-main.com (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 11 Apr 2022 05:53:53 -0700 From: Tudor Ambarus To: , CC: , , , , , , Tudor Ambarus Subject: [PATCH v3 2/3] mtd: spi-nor: Update name and description of the set_4byte_addr_mode BFPT methods Date: Mon, 11 Apr 2022 15:53:45 +0300 Message-ID: <20220411125346.118274-3-tudor.ambarus@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220411125346.118274-1-tudor.ambarus@microchip.com> References: <20220411125346.118274-1-tudor.ambarus@microchip.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org BFPT defines some standard methods to enter and exit the 4-Byte Address Mode. Use generic names for these methods and update their description. Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Reviewed-by: Michael Walle --- v3: no changes drivers/mtd/spi-nor/core.c | 2 +- drivers/mtd/spi-nor/macronix.c | 3 ++- drivers/mtd/spi-nor/micron-st.c | 3 ++- drivers/mtd/spi-nor/sfdp.c | 32 ++++++++++++++++++++------------ drivers/mtd/spi-nor/sfdp.h | 7 ++++--- drivers/mtd/spi-nor/winbond.c | 2 +- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 2b26a8cef0c3..4d45cda4f9d3 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2490,7 +2490,7 @@ static void spi_nor_init_default_params(struct spi_no= r *nor) struct device_node *np =3D spi_nor_get_flash_node(nor); =20 params->quad_enable =3D spi_nor_sr2_bit1_quad_enable; - params->set_4byte_addr_mode =3D spansion_set_4byte_addr_mode; + params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode_brwr; params->otp.org =3D &info->otp_org; =20 /* Default to 16-bit Write Status (01h) Command */ diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index d81a4cb2812b..85e8655d362c 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -105,7 +105,8 @@ static const struct flash_info macronix_nor_parts[] =3D= { static void macronix_nor_default_init(struct spi_nor *nor) { nor->params->quad_enable =3D spi_nor_sr1_bit6_quad_enable; - nor->params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode; + nor->params->set_4byte_addr_mode =3D + spi_nor_set_4byte_addr_mode_en4b_ex4b; } =20 static const struct spi_nor_fixups macronix_nor_fixups =3D { diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-s= t.c index d2903c5b5b87..2d1cbb1f37c8 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -414,7 +414,8 @@ static void micron_st_nor_default_init(struct spi_nor *= nor) nor->flags |=3D SNOR_F_HAS_LOCK; nor->flags &=3D ~SNOR_F_HAS_16BIT_SR; nor->params->quad_enable =3D NULL; - nor->params->set_4byte_addr_mode =3D micron_st_nor_set_4byte_addr_mode; + nor->params->set_4byte_addr_mode =3D + spi_nor_set_4byte_addr_mode_wren_en4b_ex4b; } =20 static void micron_st_nor_late_init(struct spi_nor *nor) diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 2e40eba3744d..c5dd79ef75c8 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -402,15 +402,20 @@ static void spi_nor_regions_sort_erase_types(struct s= pi_nor_erase_map *map) } =20 /** - * spansion_set_4byte_addr_mode() - Set 4-byte address mode for Spansion - * flashes. + * spi_nor_set_4byte_addr_mode_brwr() - Set 4-byte address mode using + * SPINOR_OP_BRWR. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * + * 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]= ) is + * used to enable/disable 4-byte address mode. When MSB is set to =E2=80= =981=E2=80=99, 4-byte + * address mode is active and A[30:24] bits are don=E2=80=99t care. Write = instruction is + * SPINOR_OP_BRWR(17h) with 1 byte of data. + * * Return: 0 on success, -errno otherwise. */ -int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +int spi_nor_set_4byte_addr_mode_brwr(struct spi_nor *nor, bool enable) { int ret; =20 @@ -434,14 +439,15 @@ int spansion_set_4byte_addr_mode(struct spi_nor *nor,= bool enable) } =20 /** - * spi_nor_set_4byte_addr_mode() - Enter/Exit 4-byte address mode. + * spi_nor_set_4byte_addr_mode_en4b_ex4b() - Enter/Exit 4-byte address mode + * using SPINOR_OP_EN4B/SPINOR_OP_EX4B. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * Return: 0 on success, -errno otherwise. */ -int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable) { int ret; =20 @@ -465,15 +471,15 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, = bool enable) } =20 /** - * micron_st_nor_set_4byte_addr_mode() - Set 4-byte address mode for ST and - * Micron flashes. + * spi_nor_set_4byte_addr_mode_wren_en4b_ex4b() - Set 4-byte address mode = usingf + * SPINOR_OP_WREN followed by SPINOR_OP_EN4B or SPINOR_OP_EX4B. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * Return: 0 on success, -errno otherwise. */ -int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +int spi_nor_set_4byte_addr_mode_wren_en4b_ex4b(struct spi_nor *nor, bool e= nable) { int ret; =20 @@ -481,7 +487,7 @@ int micron_st_nor_set_4byte_addr_mode(struct spi_nor *n= or, bool enable) if (ret) return ret; =20 - ret =3D spi_nor_set_4byte_addr_mode(nor, enable); + ret =3D spi_nor_set_4byte_addr_mode_en4b_ex4b(nor, enable); if (ret) return ret; =20 @@ -695,15 +701,17 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, =20 switch (bfpt.dwords[BFPT_DWORD(16)] & BFPT_DWORD16_4B_ADDR_MODE_MASK) { case BFPT_DWORD16_4B_ADDR_MODE_BRWR: - params->set_4byte_addr_mode =3D spansion_set_4byte_addr_mode; + params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode_brwr; break; =20 case BFPT_DWORD16_4B_ADDR_MODE_WREN_EN4B_EX4B: - params->set_4byte_addr_mode =3D micron_st_nor_set_4byte_addr_mode; + params->set_4byte_addr_mode =3D + spi_nor_set_4byte_addr_mode_wren_en4b_ex4b; break; =20 case BFPT_DWORD16_4B_ADDR_MODE_EN4B_EX4B: - params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode; + params->set_4byte_addr_mode =3D + spi_nor_set_4byte_addr_mode_en4b_ex4b; break; =20 default: diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h index 3a3744da78ba..9606610569e0 100644 --- a/drivers/mtd/spi-nor/sfdp.h +++ b/drivers/mtd/spi-nor/sfdp.h @@ -133,9 +133,10 @@ struct sfdp_parameter_header { u8 id_msb; }; =20 -int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable); -int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); -int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); +int spi_nor_set_4byte_addr_mode_brwr(struct spi_nor *nor, bool enable); +int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable= ); +int spi_nor_set_4byte_addr_mode_wren_en4b_ex4b(struct spi_nor *nor, + bool enable); int spi_nor_parse_sfdp(struct spi_nor *nor); =20 #endif /* __LINUX_MTD_SFDP_H */ diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 374ba82bff49..590e4d2c99d7 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -142,7 +142,7 @@ static int winbond_nor_set_4byte_addr_mode(struct spi_n= or *nor, bool enable) { int ret; =20 - ret =3D spi_nor_set_4byte_addr_mode(nor, enable); + ret =3D spi_nor_set_4byte_addr_mode_en4b_ex4b(nor, enable); if (ret || enable) return ret; =20 --=20 2.25.1 From nobody Thu Jun 18 23:53:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B058C433EF for ; Mon, 11 Apr 2022 12:54:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346255AbiDKM4Z (ORCPT ); Mon, 11 Apr 2022 08:56:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346273AbiDKM4O (ORCPT ); Mon, 11 Apr 2022 08:56:14 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1C933EA8C for ; Mon, 11 Apr 2022 05:53:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1649681639; x=1681217639; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TSw59bFX+PePbwORebeZ9+oAAG98COq920SoMVZze4g=; b=QJHT9sY0+/sZAnM8Ej31ot3mwvjBhGuoPsOJCwXY47xdKDfin3EgfKYF +5uxOPHNaS5npA2VkbkpvVAnC/yMg41COiVhMbLonVP6XYvZxWUvTYydL rSnbQY19K6d6xpRtgyZTJMcTVd/8tN67rK7WUgacnLOK89fvsQywI1EOW Pj8xvHVI20l0lWI/RajMmLNTe/r56sx/j93PH4oU6QeaiObUV4OhwOED5 vOzZx3z5la5IbpL0TTzzGZQdjrgP08+Hnr6l4rHKSExbdLh8FT400BWZw w7bvVWN6yeBJwFqPbL5IMdNwKMvwUl2wo1Hv3bkwW4r4uEnIWueKntXYw Q==; X-IronPort-AV: E=Sophos;i="5.90,251,1643698800"; d="scan'208";a="155133690" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Apr 2022 05:53:58 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 11 Apr 2022 05:53:58 -0700 Received: from ROB-ULT-M18064N.mchp-main.com (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 11 Apr 2022 05:53:56 -0700 From: Tudor Ambarus To: , CC: , , , , , , Tudor Ambarus Subject: [PATCH v3 3/3] mtd: spi-nor: Favor the BFPT-parsed set_4byte_addr_mode method Date: Mon, 11 Apr 2022 15:53:46 +0300 Message-ID: <20220411125346.118274-4-tudor.ambarus@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220411125346.118274-1-tudor.ambarus@microchip.com> References: <20220411125346.118274-1-tudor.ambarus@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" JESD216 SFDP defines in the BFPT standard methods to enter and exit the 4-Byte Address Mode. The flash parameters and settings that are retrieved from SFDP have higher precedence than the static initialized ones, because they should be more accurate and less error prone than those initialized statically. Favor the BFPT-parsed set_4byte_addr_mode method and use the generic core methods where possible. This patch may introduce regressions in case BFPT contains wrong data. The fix is to introduce a post_bfpt() fixup hook and update the wrong BFPT data. Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav --- v3: no changes drivers/mtd/spi-nor/core.c | 7 ++++++- drivers/mtd/spi-nor/macronix.c | 10 ++++++++-- drivers/mtd/spi-nor/micron-st.c | 9 ++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 4d45cda4f9d3..888516d98884 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2416,6 +2416,8 @@ static void spi_nor_init_fixup_flags(struct spi_nor *= nor) */ static void spi_nor_late_init_params(struct spi_nor *nor) { + struct spi_nor_flash_parameter *params =3D nor->params; + if (nor->manufacturer && nor->manufacturer->fixups && nor->manufacturer->fixups->late_init) nor->manufacturer->fixups->late_init(nor); @@ -2423,6 +2425,10 @@ static void spi_nor_late_init_params(struct spi_nor = *nor) if (nor->info->fixups && nor->info->fixups->late_init) nor->info->fixups->late_init(nor); =20 + /* Default method kept for backward compatibility. */ + if (!params->set_4byte_addr_mode) + params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode_brwr; + spi_nor_init_flags(nor); spi_nor_init_fixup_flags(nor); =20 @@ -2490,7 +2496,6 @@ static void spi_nor_init_default_params(struct spi_no= r *nor) struct device_node *np =3D spi_nor_get_flash_node(nor); =20 params->quad_enable =3D spi_nor_sr2_bit1_quad_enable; - params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode_brwr; params->otp.org =3D &info->otp_org; =20 /* Default to 16-bit Write Status (01h) Command */ diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 85e8655d362c..c267cbcc7f1d 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -105,12 +105,18 @@ static const struct flash_info macronix_nor_parts[] = =3D { static void macronix_nor_default_init(struct spi_nor *nor) { nor->params->quad_enable =3D spi_nor_sr1_bit6_quad_enable; - nor->params->set_4byte_addr_mode =3D - spi_nor_set_4byte_addr_mode_en4b_ex4b; +} + +static void macronix_nor_late_init(struct spi_nor *nor) +{ + if (!nor->params->set_4byte_addr_mode) + nor->params->set_4byte_addr_mode =3D + spi_nor_set_4byte_addr_mode_en4b_ex4b; } =20 static const struct spi_nor_fixups macronix_nor_fixups =3D { .default_init =3D macronix_nor_default_init, + .late_init =3D macronix_nor_late_init, }; =20 const struct spi_nor_manufacturer spi_nor_macronix =3D { diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-s= t.c index 2d1cbb1f37c8..9e9b107f2018 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -414,14 +414,17 @@ static void micron_st_nor_default_init(struct spi_nor= *nor) nor->flags |=3D SNOR_F_HAS_LOCK; nor->flags &=3D ~SNOR_F_HAS_16BIT_SR; nor->params->quad_enable =3D NULL; - nor->params->set_4byte_addr_mode =3D - spi_nor_set_4byte_addr_mode_wren_en4b_ex4b; } =20 static void micron_st_nor_late_init(struct spi_nor *nor) { + struct spi_nor_flash_parameter *params =3D nor->params; + if (nor->info->mfr_flags & USE_FSR) - nor->params->ready =3D micron_st_nor_ready; + params->ready =3D micron_st_nor_ready; + if (!params->set_4byte_addr_mode) + params->set_4byte_addr_mode =3D + spi_nor_set_4byte_addr_mode_wren_en4b_ex4b; } =20 static const struct spi_nor_fixups micron_st_nor_fixups =3D { --=20 2.25.1