From nobody Sun Feb 8 20:53:48 2026 Received: from chessie.everett.org (chessie.fmt1.pfcs.com [66.220.13.234]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0E058149E09; Sat, 17 Aug 2024 12:42:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.13.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898543; cv=none; b=jRXn0roWbRUXA7hrF3aDnEKrA0PizWPXxbJZ2a30N3smOi1CuKVXmceGxrheBqRbmttBooKpWECKNT/I7lFhjESfaPv2tIEIh5QWlhMfn+iXuIj0pAkdnCKHyWTikVm00HwxqWUdTWgwmtrl+HGAO3qoDLygPL1YQGGO39+dWn8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898543; c=relaxed/simple; bh=pqeHPSl08rqFIF0/JblPp9uvDV2VXrXy1J5uH3NciOY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Yy2ReyOGuqaQT+AXAigcbRku+pMb0Ohfg48UTbz4SIQGZbCYSJqzqyzeGdpjgn0DAxTlz1em3qu7t3WEUgMsjw5wg26UH96ATNseW5yB1vsHrvy6cT1twpSA2TCEQAqoAxFVlUoNr/xMiBZ3UTjdngbVFcq6oBkTCUrQv6TkWGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org; spf=pass smtp.mailfrom=nwtime.org; arc=none smtp.client-ip=66.220.13.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwtime.org Received: from localhost.localdomain (ip1f10f85d.dynamic.kabel-deutschland.de [31.16.248.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by chessie.everett.org (Postfix) with ESMTPSA id 4WmJQq5n3hzMQsP; Sat, 17 Aug 2024 12:42:11 +0000 (UTC) From: Erez Geva To: linux-mtd@lists.infradead.org, Tudor Ambarus , Pratyush Yadav , Michael Walle Cc: linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Erez Geva Subject: [PATCH v3 1/4] mtd: spi-nor: core: add manufacturer flags Date: Sat, 17 Aug 2024 14:41:37 +0200 Message-Id: <20240817124140.800637-2-erezgeva@nwtime.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240817124140.800637-1-erezgeva@nwtime.org> References: <20240817124140.800637-1-erezgeva@nwtime.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Erez Geva Add flag for always trying reading SFDP: Some vendors reuse all JEDEC IDs on manufacture table with new chips that support SFDP. Add flag for reading OTP parameters from device tree. Some vendors reuse JEDEC IDs with several chips with different OTP parameters. Alternatively we read parameters from SFDP. But the OTP parameters are absent from the SFDP. So there is not other way but to add the OTP parameters in the device tree. In this series, we will use the flags with Macronix. Signed-off-by: Erez Geva --- drivers/mtd/spi-nor/core.c | 36 ++++++++++++++++++++++++++++++----- drivers/mtd/spi-nor/core.h | 7 ++++++- drivers/mtd/spi-nor/otp.c | 6 +++--- drivers/mtd/spi-nor/winbond.c | 2 +- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index e0c4efc424f4..af522c426ac9 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2891,10 +2891,11 @@ static void spi_nor_init_params_deprecated(struct s= pi_nor *nor) =20 spi_nor_manufacturer_init_params(nor); =20 - if (nor->info->no_sfdp_flags & (SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ | - SPI_NOR_OCTAL_READ | - SPI_NOR_OCTAL_DTR_READ)) + if ((nor->info->no_sfdp_flags & (SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ | + SPI_NOR_OCTAL_READ | + SPI_NOR_OCTAL_DTR_READ)) || + nor->manufacturer->flags & SPI_NOR_MANUFACT_TTY_SFDP) spi_nor_sfdp_init_params_deprecated(nor); } =20 @@ -2911,7 +2912,32 @@ static void spi_nor_init_default_params(struct spi_n= or *nor) struct device_node *np =3D spi_nor_get_flash_node(nor); =20 params->quad_enable =3D spi_nor_sr2_bit1_quad_enable; - params->otp.org =3D info->otp; + memset(¶ms->otp.org, 0, sizeof(struct spi_nor_otp_organization)); + if (info->otp) { + memcpy(¶ms->otp.org, info->otp, sizeof(struct spi_nor_otp_organizati= on)); + } else if (nor->manufacturer->flags & SPI_NOR_MANUFACT_DT_OTP) { + /* Check for OTP information on device tree */ + u32 n_regions, len; + + if (!of_property_read_u32(np, "opt_n_regions", &n_regions) && + n_regions > 0 && + !of_property_read_u32(np, "otp_len", &len) && + len > 0) { + u32 base, offset =3D 0; + + if (n_regions > 1) { + /* If offset is not defined use length as offset */ + if (of_property_read_u32(np, "otp_offset", &offset)) + offset =3D len; + } + if (of_property_read_u32(np, "otp_base", &base)) + base =3D 0; + params->otp.org.n_regions =3D n_regions; + params->otp.org.offset =3D offset; + params->otp.org.base =3D base; + params->otp.org.len =3D len; + } + } =20 /* Default to 16-bit Write Status (01h) Command */ nor->flags |=3D SNOR_F_HAS_16BIT_SR; diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 1516b6d0dc37..237196b908dd 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -326,7 +326,7 @@ struct spi_nor_otp_ops { * @ops: OTP access ops */ struct spi_nor_otp { - const struct spi_nor_otp_organization *org; + struct spi_nor_otp_organization org; const struct spi_nor_otp_ops *ops; }; =20 @@ -560,12 +560,17 @@ struct flash_info { * @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() + * @flags: manufacturer flags */ struct spi_nor_manufacturer { const char *name; const struct flash_info *parts; unsigned int nparts; const struct spi_nor_fixups *fixups; + + u8 flags; +#define SPI_NOR_MANUFACT_TTY_SFDP BIT(0) +#define SPI_NOR_MANUFACT_DT_OTP BIT(0) }; =20 /** diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c index 9a729aa3452d..ffb7ffeb9030 100644 --- a/drivers/mtd/spi-nor/otp.c +++ b/drivers/mtd/spi-nor/otp.c @@ -11,8 +11,8 @@ =20 #include "core.h" =20 -#define spi_nor_otp_region_len(nor) ((nor)->params->otp.org->len) -#define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions) +#define spi_nor_otp_region_len(nor) ((nor)->params->otp.org.len) +#define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org.n_regions) =20 /** * spi_nor_otp_read_secr() - read security register @@ -222,7 +222,7 @@ int spi_nor_otp_is_locked_sr2(struct spi_nor *nor, unsi= gned int region) =20 static loff_t spi_nor_otp_region_start(const struct spi_nor *nor, unsigned= int region) { - const struct spi_nor_otp_organization *org =3D nor->params->otp.org; + const struct spi_nor_otp_organization *org =3D &nor->params->otp.org; =20 return org->base + region * org->offset; } diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index e065e4fd42a3..15af62aacc9a 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -307,7 +307,7 @@ static int winbond_nor_late_init(struct spi_nor *nor) { struct spi_nor_flash_parameter *params =3D nor->params; =20 - if (params->otp.org) + if (params->otp.org.n_regions) params->otp.ops =3D &winbond_nor_otp_ops; =20 /* --=20 2.39.2 From nobody Sun Feb 8 20:53:48 2026 Received: from chessie.everett.org (chessie.fmt1.pfcs.com [66.220.13.234]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C0BFE14D452; Sat, 17 Aug 2024 12:42:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.13.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898546; cv=none; b=Ws+6xmT3aKlCX/rsf4gfxrc9+ZjBC0IvCeuWhF7sc2Sgts318cpHxJNpPv80aLZYY+p5LeJjLzc4qQOCB0q2AhQ5O8SFVhF9kI0LfhAsMZc6vjCnHIyukKUNGWm5zXftUBedSQNB+/EedATQg0p0s9WlvUFZiEiAr9fY7pGhcVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898546; c=relaxed/simple; bh=oIZDCRVTYcyB2VVwR7HqVfKgVfpqLssFDdRiPnfyM3w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WwhtfVFTOw9Ma4gQKcGd5a0b1aV/MuVU92ej9kX1J6KGDYfVFcqIZbPAmmHaa9n7kTmiLgchu09rBh1lOSGIpL7Lp9qpUyQZmjGKef+rEDON3FNVeTG5zlzDrEI0+dmSqJLqJABDBzyGmJb7cinYtWbsNJUdLjmkqh5LBfJHqlU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org; spf=pass smtp.mailfrom=nwtime.org; arc=none smtp.client-ip=66.220.13.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwtime.org Received: from localhost.localdomain (ip1f10f85d.dynamic.kabel-deutschland.de [31.16.248.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by chessie.everett.org (Postfix) with ESMTPSA id 4WmJQt4GGlzMQvZ; Sat, 17 Aug 2024 12:42:14 +0000 (UTC) From: Erez Geva To: linux-mtd@lists.infradead.org, Tudor Ambarus , Pratyush Yadav , Michael Walle Cc: linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Erez Geva Subject: [PATCH v3 2/4] mtd: spi-nor: core: add generic functions Date: Sat, 17 Aug 2024 14:41:38 +0200 Message-Id: <20240817124140.800637-3-erezgeva@nwtime.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240817124140.800637-1-erezgeva@nwtime.org> References: <20240817124140.800637-1-erezgeva@nwtime.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Erez Geva Create a new internal function, spi_nor_send_cmd_internal() to reduce duplicate code. Add generic functions for use by vendor callbacks. The functions contain dispatching for using SPIMEM or using an SPI controller. It is better to leave this kind of dispatcher, out side of vendor specific code. In this patch series we use the new functions in Macronix new OTP callbacks. The new added functions: - Send an opcode without address or data. - Read a register value. - Write a register value. Signed-off-by: Erez Geva --- drivers/mtd/spi-nor/core.c | 130 +++++++++++++++++++++++++++---------- drivers/mtd/spi-nor/core.h | 27 +------- 2 files changed, 99 insertions(+), 58 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index af522c426ac9..647c843c165d 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -354,53 +354,134 @@ int spi_nor_write_any_volatile_reg(struct spi_nor *n= or, struct spi_mem_op *op, } =20 /** - * spi_nor_write_enable() - Set write enable latch with Write Enable comma= nd. + * spi_nor_send_cmd_internal() - Send instruction without address or data = to the chip. * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send * * Return: 0 on success, -errno otherwise. */ -int spi_nor_write_enable(struct spi_nor *nor) +static inline int spi_nor_send_cmd_internal(struct spi_nor *nor, u8 opcode) { int ret; =20 if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_WREN_OP; + struct spi_mem_op op =3D SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); =20 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); =20 ret =3D spi_mem_exec_op(nor->spimem, &op); } else { - ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WREN, - NULL, 0); + ret =3D spi_nor_controller_ops_write_reg(nor, opcode, NULL, 0); } =20 - if (ret) - dev_dbg(nor->dev, "error %d on Write Enable\n", ret); + return ret; +} + +/** + * spi_nor_send_cmd() - Send instruction without address or data to the ch= ip. + * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_send_cmd(struct spi_nor *nor, u8 opcode) +{ + int ret; + + ret =3D spi_nor_send_cmd_internal(nor, opcode); =20 return ret; } =20 /** - * spi_nor_write_disable() - Send Write Disable instruction to the chip. + * spi_nor_read_reg() - Send instruction without address or data to the ch= ip. * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send + * @len: register value length * * Return: 0 on success, -errno otherwise. */ -int spi_nor_write_disable(struct spi_nor *nor) +int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, size_t len) { int ret; =20 if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_WRDI_OP; + struct spi_mem_op op =3D SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(len, nor->bouncebuf, 0)); =20 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); =20 ret =3D spi_mem_exec_op(nor->spimem, &op); } else { - ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WRDI, - NULL, 0); + ret =3D spi_nor_controller_ops_read_reg(nor, opcode, nor->bouncebuf, len= ); } =20 + return ret; +} + +/* + * spi_nor_write_reg() - Send instruction without address or data to the c= hip. + * @nor: pointer to 'struct spi_nor'. + * @opcode: Command to send + * @len: register value length + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, size_t len) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op =3D SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(len, nor->bouncebuf, 0)); + + 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, opcode, nor->bouncebuf, le= n); + } + + return ret; +} + +/** + * spi_nor_write_enable() - Set write enable latch with Write Enable comma= nd. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_enable(struct spi_nor *nor) +{ + int ret; + + ret =3D spi_nor_send_cmd_internal(nor, SPINOR_OP_WREN); + + if (ret) + dev_dbg(nor->dev, "error %d on Write Enable\n", ret); + + return ret; +} + +/** + * spi_nor_write_disable() - Send Write Disable instruction to the chip. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_disable(struct spi_nor *nor) +{ + int ret; + + ret =3D spi_nor_send_cmd_internal(nor, SPINOR_OP_WRDI); + if (ret) dev_dbg(nor->dev, "error %d on Write Disable\n", ret); =20 @@ -521,18 +602,8 @@ int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_n= or *nor, bool enable) { int ret; =20 - 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); - } + ret =3D spi_nor_send_cmd_internal(nor, enable ? SPINOR_OP_EN4B : + SPINOR_OP_EX4B); =20 if (ret) dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); @@ -765,16 +836,7 @@ int spi_nor_global_block_unlock(struct spi_nor *nor) if (ret) return ret; =20 - if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_GBULK_OP; - - 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_GBULK, - NULL, 0); - } + ret =3D spi_nor_send_cmd_internal(nor, SPINOR_OP_GBULK); =20 if (ret) { dev_dbg(nor->dev, "error %d on Global Block Unlock\n", ret); diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 237196b908dd..f546bebf6ffc 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -25,18 +25,6 @@ SPI_MEM_OP_DUMMY(ndummy, 0), \ SPI_MEM_OP_DATA_IN(len, buf, 0)) =20 -#define SPI_NOR_WREN_OP \ - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - -#define SPI_NOR_WRDI_OP \ - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - #define SPI_NOR_RDSR_OP(buf) \ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 0), \ SPI_MEM_OP_NO_ADDR, \ @@ -67,24 +55,12 @@ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_IN(1, buf, 0)) =20 -#define SPI_NOR_EN4B_EX4B_OP(enable) \ - SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - #define SPI_NOR_BRWR_OP(buf) \ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_BRWR, 0), \ SPI_MEM_OP_NO_ADDR, \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_OUT(1, buf, 0)) =20 -#define SPI_NOR_GBULK_OP \ - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_GBULK, 0), \ - SPI_MEM_OP_NO_ADDR, \ - SPI_MEM_OP_NO_DUMMY, \ - SPI_MEM_OP_NO_DATA) - #define SPI_NOR_DIE_ERASE_OP(opcode, addr_nbytes, addr, dice) \ SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \ SPI_MEM_OP_ADDR(dice ? addr_nbytes : 0, addr, 0), \ @@ -604,6 +580,9 @@ extern const struct attribute_group *spi_nor_sysfs_grou= ps[]; void spi_nor_spimem_setup_op(const struct spi_nor *nor, struct spi_mem_op *op, const enum spi_nor_protocol proto); +int spi_nor_send_cmd(struct spi_nor *nor, u8 opcode); +int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, size_t len); +int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, size_t len); 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_en4b_ex4b(struct spi_nor *nor, bool enable= ); --=20 2.39.2 From nobody Sun Feb 8 20:53:48 2026 Received: from chessie.everett.org (chessie.fmt1.pfcs.com [66.220.13.234]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6580815350B; Sat, 17 Aug 2024 12:42:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.13.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898548; cv=none; b=EVNbywkzAh9zCYX3bgjEGCOkYj3te39TqNM2ybTBniugS9rQHZ6Nlbh4l+0mbvpFa4XPdoPD23PqiwbgRmyLCmGzVsAarv2r3Saw6GPi2uIL+Uknzs6qg4NTnErSb3Vnh/yKRtdBmvBhNbxdcgrKo91tZNN76T0Sb+BEzbrK0bk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898548; c=relaxed/simple; bh=8MCq0A44ypknCHYEOPZoHWh8xeuUVB1YzKZnquigXZk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nM36rJZkZJZHdK2SjcXiP0i7rYnx1iHe4KuFaAE1u2MRwadcX3Qo5ZmchNVXo4tqd0/vwZEe2QNWfxjjTfP4yvu3GcyOtZdyNuBnTby0I6tdGRV8RE9/sNpqjxmlKejGSxwySm7noOOAfEm2T5NIwoI35Mk+2QLQz/SVxFax84w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org; spf=pass smtp.mailfrom=nwtime.org; arc=none smtp.client-ip=66.220.13.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwtime.org Received: from localhost.localdomain (ip1f10f85d.dynamic.kabel-deutschland.de [31.16.248.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by chessie.everett.org (Postfix) with ESMTPSA id 4WmJQx2dGgzMQvc; Sat, 17 Aug 2024 12:42:17 +0000 (UTC) From: Erez Geva To: linux-mtd@lists.infradead.org, Tudor Ambarus , Pratyush Yadav , Michael Walle Cc: linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Erez Geva Subject: [PATCH v3 3/4] mtd: spi-nor: macronix: add support for OTP Date: Sat, 17 Aug 2024 14:41:39 +0200 Message-Id: <20240817124140.800637-4-erezgeva@nwtime.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240817124140.800637-1-erezgeva@nwtime.org> References: <20240817124140.800637-1-erezgeva@nwtime.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Erez Geva Macronix SPI-NOR support OTP. Add callbacks to read, write and lock the OTP. Notice Macronix OTP do not support erase. Every bit written with '0', can not be changed further. Signed-off-by: Erez Geva --- drivers/mtd/spi-nor/macronix.c | 185 +++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 10 ++ 2 files changed, 195 insertions(+) diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index ea6be95e75a5..8df87b414e47 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -8,6 +8,180 @@ =20 #include "core.h" =20 +/** + * macronix_nor_otp_enter() - Send Enter Secured OTP instruction to the ch= ip. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +static int macronix_nor_otp_enter(struct spi_nor *nor) +{ + int error; + + error =3D spi_nor_send_cmd(nor, SPINOR_OP_ENSO); + + if (error) + dev_dbg(nor->dev, "error %d on Macronix Enter Secured OTP\n", error); + + return error; +} + +/** + * macronix_nor_otp_exit() - Send Exit Secured OTP instruction to the chip. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +static int macronix_nor_otp_exit(struct spi_nor *nor) +{ + int error; + + error =3D spi_nor_send_cmd(nor, SPINOR_OP_EXSO); + + if (error) + dev_dbg(nor->dev, "error %d on Macronix Exit Secured OTP\n", error); + + return error; +} + +/** + * macronix_nor_otp_read() - read security register + * @nor: pointer to 'struct spi_nor' + * @addr: offset to read from + * @len: number of bytes to read + * @buf: pointer to dst buffer + * + * Return: number of bytes read successfully, -errno otherwise + */ +static int macronix_nor_otp_read(struct spi_nor *nor, loff_t addr, size_t = len, u8 *buf) +{ + int ret, error; + + error =3D macronix_nor_otp_enter(nor); + if (error) + return error; + + ret =3D spi_nor_read_data(nor, addr, len, buf); + + error =3D macronix_nor_otp_exit(nor); + + if (ret < 0) + dev_dbg(nor->dev, "error %d on Macronix read OTP data\n", ret); + else if (error) + return error; + + return ret; +} + +/** + * macronix_nor_otp_write() - write security register + * @nor: pointer to 'struct spi_nor' + * @addr: offset to write to + * @len: number of bytes to write + * @buf: pointer to src buffer + * + * Return: number of bytes written successfully, -errno otherwise + */ +static int macronix_nor_otp_write(struct spi_nor *nor, loff_t addr, size_t= len, const u8 *buf) +{ + int error, ret =3D 0; + + error =3D macronix_nor_otp_enter(nor); + if (error) + return error; + + error =3D spi_nor_write_enable(nor); + if (error) + goto otp_write_err; + + ret =3D spi_nor_write_data(nor, addr, len, buf); + if (ret < 0) { + dev_dbg(nor->dev, "error %d on Macronix write OTP data\n", ret); + goto otp_write_err; + } + + error =3D spi_nor_wait_till_ready(nor); + if (error) + dev_dbg(nor->dev, "error %d on Macronix waiting write OTP finish\n", err= or); + +otp_write_err: + + error =3D macronix_nor_otp_exit(nor); + + return ret; +} + +/** + * macronix_nor_otp_lock() - lock the OTP region + * @nor: pointer to 'struct spi_nor' + * @region: OTP region + * + * Return: 0 on success, -errno otherwise. + */ +static int macronix_nor_otp_lock(struct spi_nor *nor, unsigned int region) +{ + int error; + u8 *rdscur =3D nor->bouncebuf; + + error =3D spi_nor_read_reg(nor, SPINOR_OP_RDSCUR, 1); + if (error) { + dev_dbg(nor->dev, "error %d on read security register\n", error); + return error; + } + + switch (region) { + case 0: /* Lock 1st 4K-bit region */ + if (rdscur[0] & SEC_REG_LDS1) + return 0; /* Already locked */ + rdscur[0] |=3D SEC_REG_LDS1; + break; + case 1: /* Lock 2nd 4K-bit region */ + if (rdscur[0] & SEC_REG_LDS2) + return 0; /* Already locked */ + rdscur[0] |=3D SEC_REG_LDS2; + break; + default: + return 0; /* Unknown region */ + } + + error =3D spi_nor_write_reg(nor, SPINOR_OP_WRSCUR, 1); + if (error) + dev_dbg(nor->dev, "error %d on update security register\n", error); + + return error; +} + +/** + * macronix_nor_otp_is_locked() - get the OTP region lock status + * @nor: pointer to 'struct spi_nor' + * @region: OTP region + * + * Return: 0 on success, -errno otherwise. + */ +static int macronix_nor_otp_is_locked(struct spi_nor *nor, unsigned int re= gion) +{ + int ret; + u8 *rdscur =3D nor->bouncebuf; + + ret =3D spi_nor_read_reg(nor, SPINOR_OP_RDSCUR, 1); + if (ret) { + dev_dbg(nor->dev, "error %d on read security register\n", ret); + return ret; + } + + switch (region) { + case 0: /* 1st 4K-bit region */ + ret =3D (rdscur[0] & SEC_REG_LDS1) > 0; + break; + case 1: /* 2nd 4K-bit region */ + ret =3D (rdscur[0] & SEC_REG_LDS2) > 0; + break; + default: /* Unknown region */ + break; + } + return ret; +} + static int mx25l25635_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, @@ -190,8 +364,19 @@ static void macronix_nor_default_init(struct spi_nor *= nor) nor->params->quad_enable =3D spi_nor_sr1_bit6_quad_enable; } =20 +static const struct spi_nor_otp_ops macronix_nor_otp_ops =3D { + .read =3D macronix_nor_otp_read, + .write =3D macronix_nor_otp_write, + /* .erase =3D Macronix OTP do not support erase, */ + .lock =3D macronix_nor_otp_lock, + .is_locked =3D macronix_nor_otp_is_locked, +}; + static int macronix_nor_late_init(struct spi_nor *nor) { + if (nor->params->otp.org.n_regions) + nor->params->otp.ops =3D ¯onix_nor_otp_ops; + if (!nor->params->set_4byte_addr_mode) nor->params->set_4byte_addr_mode =3D spi_nor_set_4byte_addr_mode_en4b_ex= 4b; =20 diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index cdcfe0fd2e7d..86490c291b88 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -81,6 +81,16 @@ #define SPINOR_OP_BP 0x02 /* Byte program */ #define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */ =20 +/* Macronix OTP registers. */ +#define SPINOR_OP_RDSCUR 0x2b /* read security register */ +#define SPINOR_OP_WRSCUR 0x2f /* write security register */ +#define SPINOR_OP_ENSO 0xb1 /* enter secured OTP */ +#define SPINOR_OP_EXSO 0xc1 /* exit secured OTP */ + +/* Macronix security register values */ +#define SEC_REG_LDS1 BIT(1) /* lock-down bit 1st 4K-bit */ +#define SEC_REG_LDS2 BIT(0) /* lock-down bit 2nd 4K-bit */ + /* Used for Macronix and Winbond flashes. */ #define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ --=20 2.39.2 From nobody Sun Feb 8 20:53:48 2026 Received: from chessie.everett.org (chessie.fmt1.pfcs.com [66.220.13.234]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4E3CF153838; Sat, 17 Aug 2024 12:42:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.13.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898550; cv=none; b=R/H858IU2y0GGqBWdVbFLSlKXCAiK+IYD1uzuMoiWETADJ2Rxagyjf02SnmlDqvz55UNda8kyFlGRvx9LL2fwOda60yhh3aNHe1JOzj1CkQ6jl/b1oRbnRtcfezqZ1lagjod6efmYsUejsIKfF2bke81v4hlHw1+3brzlp+plSQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723898550; c=relaxed/simple; bh=lKZDEoa4Q2Ld7cHoD2va4rPOokrvbL0/rOLpKlaY3ys=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=I0CqQp14hhcgkcB718aIQWgyyrDMA2GQqlt6OsUFOUW5uaxqLPlLcau4S4FjQeXjzq66yBcGSvbpBq5mlk3zjpK+dKXQB4/1IHNypbey8+DxqrFtZ9FwlqtimTsBx4WCsJOwCKvmgDbi3xH3hxNXWp6+sNTiKeRDuj0PSpuANb4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org; spf=pass smtp.mailfrom=nwtime.org; arc=none smtp.client-ip=66.220.13.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwtime.org Received: from localhost.localdomain (ip1f10f85d.dynamic.kabel-deutschland.de [31.16.248.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by chessie.everett.org (Postfix) with ESMTPSA id 4WmJR00ybyzMQvj; Sat, 17 Aug 2024 12:42:19 +0000 (UTC) From: Erez Geva To: linux-mtd@lists.infradead.org, Tudor Ambarus , Pratyush Yadav , Michael Walle Cc: linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Erez Geva Subject: [PATCH v3 4/4] mtd: spi-nor: macronix: add manufacturer flags Date: Sat, 17 Aug 2024 14:41:40 +0200 Message-Id: <20240817124140.800637-5-erezgeva@nwtime.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240817124140.800637-1-erezgeva@nwtime.org> References: <20240817124140.800637-1-erezgeva@nwtime.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Erez Geva Add flag for always trying reading SFDP: All new chips from Macronix support SFDP. All old chips in the IDs table were reused by new chips. Add flag for reading OTP parameters from device tree. As Macronix reuse JEDEC IDs, there is no way to determine OTP parameters. Allow users to define the OTP parameters in device tree. Signed-off-by: Erez Geva --- drivers/mtd/spi-nor/macronix.c | 1 + 1 file changed, 1 insertion(+) -- My initial Macronix OTP code was tested with MX25l12833F. -- As I no longer have that hardware. -- I now testing with MX25L3233F connected to my BeagleBone Black -- through an 8-PIN SOP (200mil). -- The BeagleBone Black runs with Debian GNU/Linux 12. -- And use Kernel 6.6.32-ti-arm32-r5 build with -- arm-linux-gnueabihf-gcc gcc version 12.2.0 (Debian 12.2.0-14). $ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id c22016 $ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer macronix $ cat /sys/bus/spi/devices/spi0.0/spi-nor/partname mx25l3205d $ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp 53464450000101ff00000109300000ffc2000104600000ffffffffffffff ffffffffffffffffffffffffffffffffffffe520f1ffffffff0144eb086b 083b04bbeeffffffffff00ffffff00ff0c200f5210d800ffffffffffffff ffffffffffff003650269ef97764fecfffffffffffff $ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp 22d5d34af77c3628300056a0fc4bfbeafa027f544998852cf27f7cebf7881196 /sys/bus/= spi/devices/spi0.0/spi-nor/sfdp $ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities Supported read modes by the flash 1S-1S-1S opcode 0x03 mode cycles 0 dummy cycles 0 1S-1S-2S opcode 0x3b mode cycles 0 dummy cycles 8 1S-2S-2S opcode 0xbb mode cycles 0 dummy cycles 4 1S-1S-4S opcode 0x6b mode cycles 0 dummy cycles 8 1S-4S-4S opcode 0xeb mode cycles 2 dummy cycles 4 Supported page program modes by the flash 1S-1S-1S opcode 0x02 $ cat /sys/kernel/debug/spi-nor/spi0.0/params name mx25l3205d id c2 20 16 c2 20 16 size 4.00 MiB write size 1 page size 256 address nbytes 3 flags HAS_16BIT_SR opcodes read 0x03 dummy cycles 0 erase 0x20 program 0x02 8D extension none protocols read 1S-1S-1S write 1S-1S-1S register 1S-1S-1S erase commands 20 (4.00 KiB) [1] 52 (32.0 KiB) [2] d8 (64.0 KiB) [3] c7 (4.00 MiB) sector map region (in hex) | erase mask | flags ------------------+------------+---------- 00000000-003fffff | [ 123] | # mtd_debug info /dev/mtd0 mtd.type =3D MTD_NORFLASH mtd.flags =3D MTD_CAP_NORFLASH mtd.size =3D 4194304 (4M) mtd.erasesize =3D 4096 (4K) mtd.writesize =3D 1 mtd.oobsize =3D 0 regions =3D 0 -- The BeagleBone Black SPI is very slow, Tests are slow. # dd if=3D/dev/urandom of=3D./spi_test bs=3D1M count=3D2 2+0 records in 2+0 records out 2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.0682607 s, 30.7 MB/s # time mtd_debug erase /dev/mtd0 0 2097152 Erased 2097152 bytes from address 0x00000000 in flash real 0m12.703s user 0m0.000s sys 0m12.692s # time mtd_debug read /dev/mtd0 0 2097152 spi_read Copied 2097152 bytes from address 0x00000000 in flash to spi_read real 0m1.942s user 0m0.000s sys 0m0.053s # hexdump spi_read 0000000 ffff ffff ffff ffff ffff ffff ffff ffff * 0200000 # sha256sum spi_read 4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read # time mtd_debug write /dev/mtd0 0 2097152 spi_test Copied 2097152 bytes from spi_test to address 0x00000000 in flash real 0m5.883s user 0m0.006s sys 0m3.970s # time mtd_debug read /dev/mtd0 0 2097152 spi_read Copied 2097152 bytes from address 0x00000000 in flash to spi_read real 0m2.208s user 0m0.003s sys 0m0.063s # sha256sum spi* f4f5d1d0a4fef487037cdb3f1be0f9aab68ca32f2dbe8782c927f03adf623ec3 spi_read f4f5d1d0a4fef487037cdb3f1be0f9aab68ca32f2dbe8782c927f03adf623ec3 spi_test # time mtd_debug erase /dev/mtd0 0 2097152 Erased 2097152 bytes from address 0x00000000 in flash real 0m12.126s user 0m0.001s sys 0m12.115s # time mtd_debug read /dev/mtd0 0 2097152 spi_read Copied 2097152 bytes from address 0x00000000 in flash to spi_read real 0m2.611s user 0m0.000s sys 0m0.064s # sha256sum spi* 4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read f4f5d1d0a4fef487037cdb3f1be0f9aab68ca32f2dbe8782c927f03adf623ec3 spi_test -- MX25L3233F OTP uses 1 region of size of 4096 bits -- changes in device tree: compatible =3D "jedec,spi-nor"; + otp_len =3D <512>; + opt_n_regions =3D <1>; # flash_otp_info -u /dev/mtd0 Number of OTP user blocks on /dev/mtd0: 1 block 0: offset =3D 0x0000 size =3D 512 bytes [unlocked] # flash_otp_dump -u /dev/mtd0 OTP user data for /dev/mtd0 0x0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0110: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0120: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0130: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0140: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0150: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0160: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0170: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0190: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x01a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x01b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x01c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x01d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x01e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x01f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff -- Macronix OTP does not support erase! -- flash_otp_erase -- TODO: As this testing can be done once per chip, I will do it after revi= ew. # printf '\xde\xad%.0s' {1..256} | flash_otp_write -u /dev/mtd0 0 # flash_otp_lock -u /dev/mtd0 0 512 # flash_otp_info -u /dev/mtd0 -- Test that mimic old Macronix chip lack SFDP. -- In order to check how will the driver cope with an old Macronix chip. -- As we do not posses such an old chip, we will change RDSFDP to an unused= opcode. -- changes in include/linux/mtd/spi-nor.h -#define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ +#define SPINOR_OP_RDSFDP 0x57 /* Read SFDP */ # dmesg | grep spi [ 42.436974] spi-nor spi0.0: mx25l3205d (4096 Kbytes) -- No error in kernel log! # ls /sys/bus/spi/devices/spi0.0/spi-nor/ jedec_id manufacturer partname -- No SFDP, as expected! $ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities Supported read modes by the flash 1S-1S-1S opcode 0x03 mode cycles 0 dummy cycles 0 Supported page program modes by the flash 1S-1S-1S opcode 0x02 $ cat /sys/kernel/debug/spi-nor/spi0.0/params name mx25l3205d id c2 20 16 c2 20 16 size 4.00 MiB write size 1 page size 256 address nbytes 3 flags HAS_16BIT_SR opcodes read 0x03 dummy cycles 0 erase 0x20 program 0x02 8D extension none protocols read 1S-1S-1S write 1S-1S-1S register 1S-1S-1S erase commands 20 (4.00 KiB) [0] d8 (64.0 KiB) [1] c7 (4.00 MiB) sector map region (in hex) | erase mask | flags ------------------+------------+---------- 00000000-003fffff | [01 ] | diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 8df87b414e47..0e4dc6127fd1 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -393,4 +393,5 @@ const struct spi_nor_manufacturer spi_nor_macronix =3D { .parts =3D macronix_nor_parts, .nparts =3D ARRAY_SIZE(macronix_nor_parts), .fixups =3D ¯onix_nor_fixups, + .flags =3D SPI_NOR_MANUFACT_TTY_SFDP | SPI_NOR_MANUFACT_DT_OTP, }; --=20 2.39.2